From 66e6a624352b1b84ff04000ca0e4ed983373adab Mon Sep 17 00:00:00 2001 From: Olivier Maury <Olivier.Maury@inrae.fr> Date: Tue, 19 Dec 2023 17:00:36 +0100 Subject: [PATCH 01/20] =?UTF-8?q?D=C3=A9but?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../exception/ErrorMessageException.java | 4 +- ...gory.java => IndicatorsErrorCategory.java} | 14 +- .../exception/IndicatorsException.java | 31 ++++ .../exception/type/ComputationErrorType.java | 60 +++++++ .../exception/type/ResourceErrorType.java | 132 ++++++++++++++ .../exception/type/package-info.java | 20 +++ .../model/data/ResourceManager.java | 168 ++---------------- .../model/indicator/AggregationIndicator.java | 6 +- .../indicators/resources/messages.properties | 2 + .../indicators/exception/ErrorTypeTest.java | 12 +- .../model/data/ResourceManagerTest.java | 40 ++--- .../model/data/soil/SoilCalculatorTest.java | 11 +- 12 files changed, 312 insertions(+), 188 deletions(-) rename src/main/java/fr/inrae/agroclim/indicators/exception/{IndicatorErrorCategory.java => IndicatorsErrorCategory.java} (61%) create mode 100644 src/main/java/fr/inrae/agroclim/indicators/exception/IndicatorsException.java create mode 100644 src/main/java/fr/inrae/agroclim/indicators/exception/type/ComputationErrorType.java create mode 100644 src/main/java/fr/inrae/agroclim/indicators/exception/type/ResourceErrorType.java create mode 100644 src/main/java/fr/inrae/agroclim/indicators/exception/type/package-info.java diff --git a/src/main/java/fr/inrae/agroclim/indicators/exception/ErrorMessageException.java b/src/main/java/fr/inrae/agroclim/indicators/exception/ErrorMessageException.java index 0d58a8af..0ac0c704 100644 --- a/src/main/java/fr/inrae/agroclim/indicators/exception/ErrorMessageException.java +++ b/src/main/java/fr/inrae/agroclim/indicators/exception/ErrorMessageException.java @@ -8,11 +8,11 @@ import lombok.RequiredArgsConstructor; * @author omaury */ @RequiredArgsConstructor -public class ErrorMessageException extends Exception { +public abstract class ErrorMessageException extends Exception { /** * UUID for Serializable. */ - private static final long serialVersionUID = 6030595237342400004L; + private static final long serialVersionUID = 6030595237342400005L; /** * The object with details. diff --git a/src/main/java/fr/inrae/agroclim/indicators/exception/IndicatorErrorCategory.java b/src/main/java/fr/inrae/agroclim/indicators/exception/IndicatorsErrorCategory.java similarity index 61% rename from src/main/java/fr/inrae/agroclim/indicators/exception/IndicatorErrorCategory.java rename to src/main/java/fr/inrae/agroclim/indicators/exception/IndicatorsErrorCategory.java index 70ded7ac..3292bb30 100644 --- a/src/main/java/fr/inrae/agroclim/indicators/exception/IndicatorErrorCategory.java +++ b/src/main/java/fr/inrae/agroclim/indicators/exception/IndicatorsErrorCategory.java @@ -10,18 +10,22 @@ import lombok.RequiredArgsConstructor; /** * Category for error types in the Indicators library. * - * Last change $Date$ + * Last change $Date: 2023-03-16 17:36:45 +0100 (jeu. 16 mars 2023) $ * * @author omaury - * @author $Author$ - * @version $Revision$ + * @author $Author: omaury $ + * @version $Revision: 644 $ */ @RequiredArgsConstructor -public enum IndicatorErrorCategory implements ErrorCategory { +public enum IndicatorsErrorCategory implements ErrorCategory { /** * For {@link ResourceManager}. */ - RESOURCES("IND01"); + RESOURCES("IND01"), + /** + * While {@link Indicator#compute()}. + */ + COMPUTATION("IND02"); /** * Category code: prefix for {@link ErrorType#getFullCode()}. diff --git a/src/main/java/fr/inrae/agroclim/indicators/exception/IndicatorsException.java b/src/main/java/fr/inrae/agroclim/indicators/exception/IndicatorsException.java new file mode 100644 index 00000000..b910e449 --- /dev/null +++ b/src/main/java/fr/inrae/agroclim/indicators/exception/IndicatorsException.java @@ -0,0 +1,31 @@ +package fr.inrae.agroclim.indicators.exception; + +import java.io.Serializable; +import java.util.List; + +/** + * An exception with {@link ErrorMessage} to describe the error in the Indicators library to the user. + * + * Last changed : $Date: 2023-03-16 17:39:08 +0100 (jeu. 16 mars 2023) $ + * + * @author $Author: omaury $ + * @version $Revision: 1247 $ + */ +public class IndicatorsException extends ErrorMessageException { + + /** + * UUID for Serializable. + */ + private static final long serialVersionUID = 6030595237342400006L; + + /** + * Constructor. + * + * @param errorType Error type. + * @param arguments Arguments for the message. + */ + public IndicatorsException(final ErrorType errorType, final Serializable... arguments) { + super(new ErrorMessage("fr.inrae.agroclim.indicators.resources.messages", errorType, List.of(arguments))); + } + +} diff --git a/src/main/java/fr/inrae/agroclim/indicators/exception/type/ComputationErrorType.java b/src/main/java/fr/inrae/agroclim/indicators/exception/type/ComputationErrorType.java new file mode 100644 index 00000000..98523c07 --- /dev/null +++ b/src/main/java/fr/inrae/agroclim/indicators/exception/type/ComputationErrorType.java @@ -0,0 +1,60 @@ +package fr.inrae.agroclim.indicators.exception.type; + +import fr.inrae.agroclim.indicators.exception.ErrorCategory; +import fr.inrae.agroclim.indicators.exception.ErrorType; +import fr.inrae.agroclim.indicators.exception.IndicatorsErrorCategory; +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +/** + * Keys from messages.properties used to warn about errors in {@link Indicator#compute()}. + */ +@RequiredArgsConstructor +public enum ComputationErrorType implements ErrorType { + /** + * Definition of the indicator is not good. + */ + WRONG_DEFINITION(null, "01"), + /** + * Criteria should be NoCriteria or SimpleCriteria. + */ + CRITERIA_ISNT_NOCRITERIA_SIMPLECRITERIA(WRONG_DEFINITION, "02"); + + /** + * Parent refers to the resource part. + */ + @Getter + private final ComputationErrorType parent; + + /** + * Subcode for the error. + */ + @Getter + private final String subCode; + + @Override + public ErrorCategory getCategory() { + return IndicatorsErrorCategory.COMPUTATION; + } + /** + * @return partial I18n key for messages.properties + */ + private String getShortKey() { + return name().toLowerCase().replace("_", "."); + } + /** + * @return Key for Resource/I18nResource. + */ + @Override + public String getI18nKey() { + if (parent != null) { + return "error.computation." + parent.getShortKey() + "." + getShortKey(); + } + return "error.computation." + getShortKey(); + } + + @Override + public String getName() { + return name(); + } +} diff --git a/src/main/java/fr/inrae/agroclim/indicators/exception/type/ResourceErrorType.java b/src/main/java/fr/inrae/agroclim/indicators/exception/type/ResourceErrorType.java new file mode 100644 index 00000000..aef77fda --- /dev/null +++ b/src/main/java/fr/inrae/agroclim/indicators/exception/type/ResourceErrorType.java @@ -0,0 +1,132 @@ +package fr.inrae.agroclim.indicators.exception.type; + +import fr.inrae.agroclim.indicators.exception.ErrorCategory; +import fr.inrae.agroclim.indicators.exception.ErrorType; +import fr.inrae.agroclim.indicators.exception.IndicatorsErrorCategory; +import lombok.Getter; + +/** + * Keys from messages.properties used to warn about errors in {@link ResourceManager}. + */ +public enum ResourceErrorType implements ErrorType { + /** + * Climate, topic. + */ + CLIMATE("01", null, "resource.climatic"), + /** + * No climate data. + */ + CLIMATE_EMPTY("02", CLIMATE, "empty"), + /** + * Not enough data. + */ + CLIMATE_SIZE_WRONG("03", CLIMATE, "size.wrong"), + /** + * Years of climate, topic. + */ + CLIMATIC_YEARS("04", null, "resource.climatic.years"), + /** + * No years of climate. + */ + CLIMATE_YEARS_EMPTY("05", CLIMATIC_YEARS, "empty"), + /** + * Not enough data. + */ + CLIMATE_YEARS_MISSING("06", CLIMATIC_YEARS, "missing"), + /** + * Phenology, topic. + */ + PHENO("07", null, "resource.pheno"), + /** + * No phenological data. + */ + PHENO_EMPTY("08", PHENO, "empty"), + /** + * Years of phenology, topic. + */ + PHENO_YEARS("09", null, "resource.pheno.years"), + /** + * No years of phenology. + */ + PHENO_YEARS_EMPTY("10", PHENO_YEARS, "empty"), + /** + * Not enough data. + */ + PHENO_YEARS_MISSING("11", PHENO_YEARS, "missing"), + /** + * Resource in general, topic. + */ + RESOURCE("12", null, "resource"), + /** + * Setting not set. + */ + RESOURCE_CROPDEVELOPMENT_YEARS("13", RESOURCE, "cropdevelopmentyears.null"), + /** + * Soil, topic. + */ + SOIL("14", null, "resource.soil"), + /** + * Not enough data. + */ + SOIL_SIZE_WRONG("15", SOIL, "size.wrong"), + /** + * Variables, topic. + */ + VARIABLES("16", null, "resource.variables"), + /** + * No variable. + */ + VARIABLES_EMPTY("17", VARIABLES, "empty"), + /** + * No variale. + */ + VARIABLES_MISSING("18", VARIABLES, "missing"); + /** + * Key for Resource/I18nResource. + */ + private final String key; + /** + * Subcode for the error. + */ + @Getter + private final String subCode; + /** + * Parent refers to the resource part. + */ + @Getter + private final ResourceErrorType parent; + + /** + * Constructor. + * + * @param c Subcode for the error. + * @param p Parent refers to the resource part. + * @param k Key for Resource/I18nResource. + */ + ResourceErrorType(final String c, final ResourceErrorType p, final String k) { + parent = p; + key = k; + subCode = c; + } + + @Override + public ErrorCategory getCategory() { + return IndicatorsErrorCategory.RESOURCES; + } + + /** + * @return Key for Resource/I18nResource. + */ + @Override + public String getI18nKey() { + if (parent != null) { + return "error.evaluation." + parent.key + "." + key; + } + return "error.evaluation." + key; + } + + @Override + public String getName() { + return name(); + } +} diff --git a/src/main/java/fr/inrae/agroclim/indicators/exception/type/package-info.java b/src/main/java/fr/inrae/agroclim/indicators/exception/type/package-info.java new file mode 100644 index 00000000..647131bf --- /dev/null +++ b/src/main/java/fr/inrae/agroclim/indicators/exception/type/package-info.java @@ -0,0 +1,20 @@ +/** + * This file is part of Indicators. + * + * Indicators is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Indicators is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Indicators. If not, see <https://www.gnu.org/licenses/>. + */ +/** + * {@link ErrorType} implementations for error handling. + */ +package fr.inrae.agroclim.indicators.exception.type; diff --git a/src/main/java/fr/inrae/agroclim/indicators/model/data/ResourceManager.java b/src/main/java/fr/inrae/agroclim/indicators/model/data/ResourceManager.java index 9d373087..6c091cd1 100644 --- a/src/main/java/fr/inrae/agroclim/indicators/model/data/ResourceManager.java +++ b/src/main/java/fr/inrae/agroclim/indicators/model/data/ResourceManager.java @@ -26,10 +26,8 @@ import java.util.Map; import java.util.Objects; import java.util.Set; -import fr.inrae.agroclim.indicators.exception.ErrorCategory; import fr.inrae.agroclim.indicators.exception.ErrorMessage; -import fr.inrae.agroclim.indicators.exception.ErrorType; -import fr.inrae.agroclim.indicators.exception.IndicatorErrorCategory; +import fr.inrae.agroclim.indicators.exception.type.ResourceErrorType; import fr.inrae.agroclim.indicators.model.TimeScale; import fr.inrae.agroclim.indicators.model.data.Variable.Type; import fr.inrae.agroclim.indicators.model.data.climate.ClimaticResource; @@ -37,7 +35,6 @@ import fr.inrae.agroclim.indicators.model.data.phenology.PhenologicalResource; import fr.inrae.agroclim.indicators.util.DateUtils; import lombok.Getter; import lombok.NonNull; -import lombok.RequiredArgsConstructor; import lombok.Setter; import lombok.extern.log4j.Log4j2; @@ -47,141 +44,14 @@ import lombok.extern.log4j.Log4j2; * * Its responsibility is data storage and checking data consistency. * - * Last changed : $Date$ + * Last changed : $Date: 2023-03-16 17:36:45 +0100 (jeu. 16 mars 2023) $ * - * @author $Author$ - * @version $Revision$ + * @author $Author: omaury $ + * @version $Revision: 644 $ */ @Log4j2 public final class ResourceManager implements Serializable, Cloneable { - /** - * Keys from messages.properties used to warn about errors. - */ - @RequiredArgsConstructor - public enum ErrorI18nKey implements ErrorType { - /** - * Climate, topic. - */ - CLIMATE("01", null, "resource.climatic"), - /** - * No climate data. - */ - CLIMATE_EMPTY("02", CLIMATE, "empty"), - /** - * Not enough data. - */ - CLIMATE_SIZE_WRONG("03", CLIMATE, "size.wrong"), - /** - * Years of climate, topic. - */ - CLIMATIC_YEARS("04", null, "resource.climatic.years"), - /** - * No years of climate. - */ - CLIMATE_YEARS_EMPTY("05", CLIMATIC_YEARS, "empty"), - /** - * Not enough data. - */ - CLIMATE_YEARS_MISSING("06", CLIMATIC_YEARS, "missing"), - /** - * Phenology, topic. - */ - PHENO("07", null, "resource.pheno"), - /** - * No phenological data. - */ - PHENO_EMPTY("08", PHENO, "empty"), - /** - * Years of phenology, topic. - */ - PHENO_YEARS("09", null, "resource.pheno.years"), - /** - * No years of phenology. - */ - PHENO_YEARS_EMPTY("10", PHENO_YEARS, "empty"), - /** - * Not enough data. - */ - PHENO_YEARS_MISSING("11", PHENO_YEARS, "missing"), - /** - * Resource in general, topic. - */ - RESOURCE("12", null, "resource"), - /** - * Setting not set. - */ - RESOURCE_CROPDEVELOPMENT_YEARS("13", RESOURCE, "cropdevelopmentyears.null"), - /** - * Soil, topic. - */ - SOIL("14", null, "resource.soil"), - /** - * Not enough data. - */ - SOIL_SIZE_WRONG("15", SOIL, "size.wrong"), - /** - * Variables, topic. - */ - VARIABLES("16", null, "resource.variables"), - /** - * No variable. - */ - VARIABLES_EMPTY("17", VARIABLES, "empty"), - /** - * No variale. - */ - VARIABLES_MISSING("18", VARIABLES, "missing"); - /** - * Key for Resource/I18nResource. - */ - private final String key; - /** - * Subcode for the error. - */ - @Getter - private final String subCode; - /** - * Parent refers to the resource part. - */ - @Getter - private final ErrorI18nKey parent; - - /** - * Constructor. - * - * @param c Subcode for the error. - * @param p Parent refers to the resource part. - * @param k Key for Resource/I18nResource. - */ - ErrorI18nKey(final String c, final ErrorI18nKey p, final String k) { - parent = p; - key = k; - subCode = c; - } - - @Override - public ErrorCategory getCategory() { - return IndicatorErrorCategory.RESOURCES; - } - - /** - * @return Key for Resource/I18nResource. - */ - @Override - public String getI18nKey() { - if (parent != null) { - return "error.evaluation." + parent.key + "." + key; - } - return "error.evaluation." + key; - } - - @Override - public String getName() { - return name(); - } - } - /** * UUID for Serializable. */ @@ -191,8 +61,8 @@ public final class ResourceManager implements Serializable, Cloneable { * @param errorI18nKey Message key from .property resource. */ private static void addErrorMessage( - final Map<ErrorI18nKey, ErrorMessage> errors, - final ErrorI18nKey errorI18nKey) { + final Map<ResourceErrorType, ErrorMessage> errors, + final ResourceErrorType errorI18nKey) { errors.put(errorI18nKey.getParent(), new ErrorMessage( "fr.inrae.agroclim.indicators.resources.messages", errorI18nKey, null)); @@ -259,21 +129,21 @@ public final class ResourceManager implements Serializable, Cloneable { /** * @return consistency errors */ - public Map<ErrorI18nKey, ErrorMessage> getConsitencyErrors() { - final Map<ErrorI18nKey, ErrorMessage> errors = new EnumMap<>(ErrorI18nKey.class); + public Map<ResourceErrorType, ErrorMessage> getConsitencyErrors() { + final Map<ResourceErrorType, ErrorMessage> errors = new EnumMap<>(ResourceErrorType.class); // variables not set ? if (variables == null) { - addErrorMessage(errors, ErrorI18nKey.VARIABLES_MISSING); + addErrorMessage(errors, ResourceErrorType.VARIABLES_MISSING); return errors; } if (variables.isEmpty()) { - addErrorMessage(errors, ErrorI18nKey.VARIABLES_EMPTY); + addErrorMessage(errors, ResourceErrorType.VARIABLES_EMPTY); return errors; } // empty climate final List<Integer> climaticYears = climaticResource.getYears(); if (hasClimaticVariables() && climaticResource.getData().isEmpty()) { - addErrorMessage(errors, ErrorI18nKey.CLIMATE_EMPTY); + addErrorMessage(errors, ResourceErrorType.CLIMATE_EMPTY); } else { // missing days or hours final int nbClimatic = climaticResource.getData().size(); @@ -285,12 +155,12 @@ public final class ResourceManager implements Serializable, Cloneable { nb = nb * DateUtils.NB_OF_HOURS_IN_DAY; } if (nbClimatic != nb) { - addErrorMessage(errors, ErrorI18nKey.CLIMATE_SIZE_WRONG); + addErrorMessage(errors, ResourceErrorType.CLIMATE_SIZE_WRONG); } } // empty phenology if (phenologicalResource.isEmpty()) { - addErrorMessage(errors, ErrorI18nKey.PHENO_EMPTY); + addErrorMessage(errors, ResourceErrorType.PHENO_EMPTY); } if (!errors.isEmpty()) { return errors; @@ -298,16 +168,16 @@ public final class ResourceManager implements Serializable, Cloneable { // period final List<Integer> phenoYears = phenologicalResource.getYears(); if (hasClimaticVariables() && climaticYears.isEmpty()) { - addErrorMessage(errors, ErrorI18nKey.CLIMATE_YEARS_EMPTY); + addErrorMessage(errors, ResourceErrorType.CLIMATE_YEARS_EMPTY); } if (phenoYears.isEmpty()) { - addErrorMessage(errors, ErrorI18nKey.PHENO_YEARS_EMPTY); + addErrorMessage(errors, ResourceErrorType.PHENO_YEARS_EMPTY); } if (!errors.isEmpty()) { return errors; } if (cropDevelopmentYears == null) { - addErrorMessage(errors, ErrorI18nKey.RESOURCE_CROPDEVELOPMENT_YEARS); + addErrorMessage(errors, ResourceErrorType.RESOURCE_CROPDEVELOPMENT_YEARS); return errors; } // Phenology data drives evaluation, so @@ -325,9 +195,9 @@ public final class ResourceManager implements Serializable, Cloneable { theMissing.removeAll(climaticYears); final ErrorMessage error = new ErrorMessage( "fr.inrae.agroclim.indicators.resources.messages", - ErrorI18nKey.CLIMATE_YEARS_MISSING, + ResourceErrorType.CLIMATE_YEARS_MISSING, theMissing); - errors.put(ErrorI18nKey.CLIMATE_YEARS_MISSING.getParent(), error); + errors.put(ResourceErrorType.CLIMATE_YEARS_MISSING.getParent(), error); } if (!errors.isEmpty()) { return errors; @@ -340,7 +210,7 @@ public final class ResourceManager implements Serializable, Cloneable { } final int nbSoil = climaticResource.getData().size(); if (nbSoil != nbDays) { - addErrorMessage(errors, ErrorI18nKey.SOIL_SIZE_WRONG); + addErrorMessage(errors, ResourceErrorType.SOIL_SIZE_WRONG); } } if (errors.isEmpty()) { diff --git a/src/main/java/fr/inrae/agroclim/indicators/model/indicator/AggregationIndicator.java b/src/main/java/fr/inrae/agroclim/indicators/model/indicator/AggregationIndicator.java index 60969fdb..e48ad253 100644 --- a/src/main/java/fr/inrae/agroclim/indicators/model/indicator/AggregationIndicator.java +++ b/src/main/java/fr/inrae/agroclim/indicators/model/indicator/AggregationIndicator.java @@ -8,7 +8,9 @@ import java.util.stream.DoubleStream; import javax.xml.bind.annotation.XmlElement; import fr.inrae.agroclim.indicators.exception.FunctionalException; +import fr.inrae.agroclim.indicators.exception.IndicatorsException; import fr.inrae.agroclim.indicators.exception.TechnicalException; +import fr.inrae.agroclim.indicators.exception.type.ComputationErrorType; import fr.inrae.agroclim.indicators.model.criteria.Criteria; import fr.inrae.agroclim.indicators.model.criteria.NoCriteria; import fr.inrae.agroclim.indicators.model.criteria.SimpleCriteria; @@ -24,7 +26,7 @@ import lombok.Setter; * Aggregate value defined in a {@link SimpleCriteria} using a {@link Function} * on {@link DoubleStream} created for {@link AggregationIndicator#variable}. * - * Last changed : $Date$ + * Last changed : $Date: 2023-06-16 10:36:46 +0200 (ven., 16 juin 2023) $ * * @author omaury */ @@ -84,7 +86,7 @@ public abstract class AggregationIndicator extends SimpleIndicatorWithCriteria i .filter(predicate) // .mapToDouble(criteria::getValueOf); } else { - throw new FunctionalException("criteria is neither NoCriteria nor SimpleCriteria!"); + throw new IndicatorsException(ComputationErrorType.CRITERIA_ISNT_NOCRITERIA_SIMPLECRITERIA, getId()); } return aggregate(stream); } diff --git a/src/main/resources/fr/inrae/agroclim/indicators/resources/messages.properties b/src/main/resources/fr/inrae/agroclim/indicators/resources/messages.properties index b9d6735b..aed9f283 100644 --- a/src/main/resources/fr/inrae/agroclim/indicators/resources/messages.properties +++ b/src/main/resources/fr/inrae/agroclim/indicators/resources/messages.properties @@ -20,6 +20,8 @@ error.climate.dates=For the year {0}, available dates are from {1} to {2}. error.climate.missing=No climatic daily data for phase {0}-{1} (days {2} -> {3}) in {4}. error.climate.no.data=No data were retrieved. error.climate.wrong.headers=Wrong number of headers! {0} headers are in the file: {1}, but {2} headers are defined: {3}. +error.computation.wrong.definition=The indicator "{0}" is not well defined: {1}. +error.computation.wrong.definition.criteria.isnt.nocriteria.simplecriteria=criteria is neither NoCriteria nor SimpleCriteria! error.evaluation.resource=Error for resources! error.evaluation.resource.climatic=Error for climatic data set in resources! error.evaluation.resource.climatic.empty=No climatic data set in resources! diff --git a/src/test/java/fr/inrae/agroclim/indicators/exception/ErrorTypeTest.java b/src/test/java/fr/inrae/agroclim/indicators/exception/ErrorTypeTest.java index 695c625b..00cda328 100644 --- a/src/test/java/fr/inrae/agroclim/indicators/exception/ErrorTypeTest.java +++ b/src/test/java/fr/inrae/agroclim/indicators/exception/ErrorTypeTest.java @@ -1,5 +1,7 @@ package fr.inrae.agroclim.indicators.exception; +import fr.inrae.agroclim.indicators.exception.type.ComputationErrorType; +import fr.inrae.agroclim.indicators.exception.type.ResourceErrorType; import static org.junit.Assert.assertTrue; import java.util.ArrayList; @@ -15,16 +17,15 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; -import fr.inrae.agroclim.indicators.model.data.ResourceManager; import fr.inrae.agroclim.indicators.resources.I18n; /** * Ensure all implementations of {@link ErrorType} are well defined. * - * Last changed : $Date$ + * Last changed : $Date: 2023-03-16 17:36:45 +0100 (jeu. 16 mars 2023) $ * - * @author $Author$ - * @version $Revision$ + * @author $Author: omaury $ + * @version $Revision: 644 $ */ @RunWith(Parameterized.class) public class ErrorTypeTest { @@ -38,7 +39,7 @@ public class ErrorTypeTest { */ @Parameterized.Parameters public static List<Class<? extends Enum<?>>> data() { - return Arrays.asList(ResourceManager.ErrorI18nKey.class); + return List.of(ComputationErrorType.class, ResourceErrorType.class); } /** @@ -84,6 +85,7 @@ public class ErrorTypeTest { if (codes.contains(k.getSubCode())) { duplicates.add(k.getSubCode()); } + codes.add(k.getSubCode()); } assertTrue(duplicates.isEmpty()); } diff --git a/src/test/java/fr/inrae/agroclim/indicators/model/data/ResourceManagerTest.java b/src/test/java/fr/inrae/agroclim/indicators/model/data/ResourceManagerTest.java index 6880d2ba..d69f5cfe 100644 --- a/src/test/java/fr/inrae/agroclim/indicators/model/data/ResourceManagerTest.java +++ b/src/test/java/fr/inrae/agroclim/indicators/model/data/ResourceManagerTest.java @@ -31,17 +31,17 @@ import java.util.Set; import org.junit.Test; import fr.inrae.agroclim.indicators.exception.ErrorMessage; -import fr.inrae.agroclim.indicators.model.data.ResourceManager.ErrorI18nKey; +import fr.inrae.agroclim.indicators.exception.type.ResourceErrorType; import fr.inrae.agroclim.indicators.model.data.phenology.AnnualStageData; import fr.inrae.agroclim.indicators.resources.Messages; /** * Test the resource manager. * - * Last changed : $Date$ + * Last changed : $Date: 2023-03-16 17:36:45 +0100 (jeu. 16 mars 2023) $ * - * @author $Author$ - * @version $Revision$ + * @author $Author: omaury $ + * @version $Revision: 644 $ */ public final class ResourceManagerTest extends DataTestHelper { @@ -53,11 +53,11 @@ public final class ResourceManagerTest extends DataTestHelper { final ResourceManager mgr = new ResourceManager(); // without variables - Map<ErrorI18nKey, ErrorMessage> errors = mgr.getConsitencyErrors(); + Map<ResourceErrorType, ErrorMessage> errors = mgr.getConsitencyErrors(); assertNotNull("Empty ResourceManager must return consistency errors!", errors); - final Set<ErrorI18nKey> expectedErrors = new HashSet<>(); - expectedErrors.add(ErrorI18nKey.VARIABLES); + final Set<ResourceErrorType> expectedErrors = new HashSet<>(); + expectedErrors.add(ResourceErrorType.VARIABLES); assertEquals("ResourceManager without variables must have errors!", expectedErrors, errors.keySet()); expectedErrors.clear(); @@ -67,8 +67,8 @@ public final class ResourceManagerTest extends DataTestHelper { variables.add(Variable.TMEAN); variables.add(Variable.SOILWATERCONTENT); mgr.setVariables(variables); - expectedErrors.addAll(Arrays.asList(ErrorI18nKey.CLIMATE, - ErrorI18nKey.PHENO)); + expectedErrors.addAll(Arrays.asList(ResourceErrorType.CLIMATE, + ResourceErrorType.PHENO)); errors = mgr.getConsitencyErrors(); assertNotNull("Empty ResourceManager must return consistency errors!", errors); @@ -89,14 +89,14 @@ public final class ResourceManagerTest extends DataTestHelper { "radiation", "rain", "tmean", "tmin", "tmax", "rh", "wind"}; mgr.getClimaticResource().setData(getClimaticData( "climate-missing-data.csv", ";", headers)); - final Map<ErrorI18nKey, ErrorMessage> errors = mgr.getConsitencyErrors(); + final Map<ResourceErrorType, ErrorMessage> errors = mgr.getConsitencyErrors(); final String subject = "ResourceManager with missing days in climatic " + "resource "; assertNotNull(subject + "must return consistency errors!", errors); assertTrue(subject + "must have errors on climatic resources!", - errors.keySet().contains(ErrorI18nKey.CLIMATE)); + errors.keySet().contains(ResourceErrorType.CLIMATE)); assertEquals(subject + "must have errors on climatic resources!", - errors.get(ErrorI18nKey.CLIMATE).getType().getI18nKey(), ErrorI18nKey.CLIMATE_SIZE_WRONG.getI18nKey()); + errors.get(ResourceErrorType.CLIMATE).getType().getI18nKey(), ResourceErrorType.CLIMATE_SIZE_WRONG.getI18nKey()); } /** @@ -111,7 +111,7 @@ public final class ResourceManagerTest extends DataTestHelper { mgr.setVariables(variables); mgr.getClimaticResource().setData(getClimatic2015Data()); mgr.getPhenologicalResource().setData(getPheno2015Data()); - final Map<ErrorI18nKey, ErrorMessage> errors = mgr.getConsitencyErrors(); + final Map<ResourceErrorType, ErrorMessage> errors = mgr.getConsitencyErrors(); assertNull(errors); } @@ -125,11 +125,11 @@ public final class ResourceManagerTest extends DataTestHelper { variables.add(Variable.TMEAN); mgr.setVariables(variables); mgr.getClimaticResource().setData(getClimatic2015Data()); - final Map<ErrorI18nKey, ErrorMessage> errors = mgr.getConsitencyErrors(); + final Map<ResourceErrorType, ErrorMessage> errors = mgr.getConsitencyErrors(); final String subject = "ResourceManager with only climatic resource "; assertNotNull(subject + "must return consistency errors!", errors); - final Set<ErrorI18nKey> expectedErrors = new HashSet<>(); - expectedErrors.add(ErrorI18nKey.PHENO); + final Set<ResourceErrorType> expectedErrors = new HashSet<>(); + expectedErrors.add(ResourceErrorType.PHENO); assertEquals(subject + "must have errors on pheno resources", expectedErrors, errors.keySet()); } @@ -148,10 +148,10 @@ public final class ResourceManagerTest extends DataTestHelper { final List<AnnualStageData> data = getPhenoSampleData(); data.remove(data.size() - 1); mgr.getPhenologicalResource().setData(data); - final Map<ErrorI18nKey, ErrorMessage> errors = mgr.getConsitencyErrors(); + final Map<ResourceErrorType, ErrorMessage> errors = mgr.getConsitencyErrors(); assertNotNull(errors); - final Set<ErrorI18nKey> expectedErrors = new HashSet<>(); - expectedErrors.add(ErrorI18nKey.CLIMATIC_YEARS); + final Set<ResourceErrorType> expectedErrors = new HashSet<>(); + expectedErrors.add(ResourceErrorType.CLIMATIC_YEARS); final String subject = "ResourceManager with only climatic data in 2015 " + "must have errors on climatic resources"; assertEquals(subject, expectedErrors, errors.keySet()); @@ -162,7 +162,7 @@ public final class ResourceManagerTest extends DataTestHelper { */ @Test public void error18nKey() { - for (final ErrorI18nKey val : ErrorI18nKey.values()) { + for (final ResourceErrorType val : ResourceErrorType.values()) { if (val.getParent() != null) { assertFalse(val.getI18nKey() + " must be translated!", Messages.get(val.getI18nKey()).startsWith("!")); } diff --git a/src/test/java/fr/inrae/agroclim/indicators/model/data/soil/SoilCalculatorTest.java b/src/test/java/fr/inrae/agroclim/indicators/model/data/soil/SoilCalculatorTest.java index dccd1bab..5f87c24c 100644 --- a/src/test/java/fr/inrae/agroclim/indicators/model/data/soil/SoilCalculatorTest.java +++ b/src/test/java/fr/inrae/agroclim/indicators/model/data/soil/SoilCalculatorTest.java @@ -18,6 +18,7 @@ package fr.inrae.agroclim.indicators.model.data.soil; import fr.inrae.agroclim.indicators.exception.ErrorMessage; import fr.inrae.agroclim.indicators.exception.TechnicalException; +import fr.inrae.agroclim.indicators.exception.type.ResourceErrorType; import fr.inrae.agroclim.indicators.model.Evaluation; import fr.inrae.agroclim.indicators.model.EvaluationSettings; import static org.junit.Assert.assertEquals; @@ -51,10 +52,10 @@ import java.util.TimeZone; /** * Test Soil data calculator from ClimaticDailyData. * - * Last changed : $Date$ + * Last changed : $Date: 2023-05-30 15:49:13 +0200 (mar. 30 mai 2023) $ * - * @author $Author$ - * @version $Revision$ + * @author $Author: omaury $ + * @version $Revision: 656 $ */ public final class SoilCalculatorTest extends DataTestHelper { @@ -273,7 +274,7 @@ public final class SoilCalculatorTest extends DataTestHelper { final int haltComparison = 582; final double tolerance = 0.01; final String diffMsg = """ - + At %d-%02d-%02d (%d), %s=%.3f != expected %.3f!"""; List<String> computationErrors = new ArrayList<>(); int i = 0; @@ -371,7 +372,7 @@ public final class SoilCalculatorTest extends DataTestHelper { settings.getSoilLoader().setCalculator(calc); // 4. initialize resources evaluation.initializeResources(); - final Map<ResourceManager.ErrorI18nKey, ErrorMessage> errors; + final Map<ResourceErrorType, ErrorMessage> errors; errors = evaluation.getResourceManager().getConsitencyErrors(); assertNull("No error must be found", errors); // Tests -- GitLab From d5efe59d12d63bbd57d29ea72cca51f38f81b545 Mon Sep 17 00:00:00 2001 From: Olivier Maury <Olivier.Maury@inrae.fr> Date: Wed, 20 Dec 2023 16:18:16 +0100 Subject: [PATCH 02/20] Continuer --- .gitlab-ci.yml | 2 +- .../exception/ErrorMessageException.java | 17 ++++++ .../exception/FunctionalException.java | 3 + .../exception/IndicatorsException.java | 13 ++++ .../exception/TechnicalException.java | 3 + .../exception/ThrowingToDoubleFunction.java | 40 ++++++++++++ .../exception/type/ComputationErrorType.java | 61 ++++++++++++++++++- .../exception/type/ResourceErrorType.java | 37 +++++------ .../agroclim/indicators/model/Evaluation.java | 55 +++++++---------- .../indicators/model/JEXLFormula.java | 37 +++++------ .../indicators/model/Quantifiable.java | 11 +--- .../model/criteria/ComparisonCriteria.java | 8 ++- .../model/criteria/CompositeCriteria.java | 13 ++-- .../indicators/model/criteria/Criteria.java | 7 +-- .../model/criteria/FormulaCriteria.java | 20 +++--- .../indicators/model/criteria/NoCriteria.java | 4 +- .../model/criteria/SimpleCriteria.java | 9 ++- .../model/criteria/VariableCriteria.java | 21 ++++--- .../aggregation/AggregationFunction.java | 7 +-- .../function/aggregation/JEXLFunction.java | 4 +- .../model/indicator/AggregationIndicator.java | 52 +++++++++------- .../model/indicator/AverageOfDiff.java | 6 +- .../model/indicator/CompositeIndicator.java | 11 ++-- .../indicators/model/indicator/DayOfYear.java | 9 ++- .../indicators/model/indicator/DiffOfSum.java | 6 +- .../indicators/model/indicator/Formula.java | 16 +++-- .../indicators/model/indicator/Frequency.java | 6 +- .../model/indicator/InjectedParameter.java | 6 +- .../model/indicator/MaxWaveLength.java | 11 ++-- .../model/indicator/NumberOfDays.java | 6 +- .../model/indicator/NumberOfWaves.java | 11 ++-- .../model/indicator/PhaseLength.java | 6 +- .../PotentialSowingDaysFrequency.java | 12 ++-- .../indicators/model/indicator/Quotient.java | 28 +++------ .../model/indicator/SimpleIndicator.java | 23 ++----- .../indicators/model/indicator/Tamm.java | 6 +- .../model/CulturalPracticesTest.java | 5 +- .../model/EvaluationHourlyTest.java | 5 +- .../model/EvaluationRobertTest.java | 5 +- .../indicators/model/EvaluationTest.java | 21 +++---- .../EvaluationWithoutAggregationTest.java | 9 +-- .../model/EvalutationCustomHeadersTest.java | 5 +- .../indicators/model/JEXLFormulaTest.java | 6 +- .../indicators/model/KnowledgeTest.java | 1 + .../indicators/model/MMarjouTest.java | 5 +- .../indicators/model/RaidayMeantTest.java | 8 +-- .../model/StageDeltaEvaluationTest.java | 4 +- .../model/criteria/CompositeCriteriaTest.java | 22 +++---- .../model/criteria/FormulaCriteriaTest.java | 9 +-- .../model/criteria/SimpleCriteriaTest.java | 11 ++-- .../aggregation/JEXLFunctionTest.java | 20 +++--- .../model/indicator/AverageOfDiffTest.java | 5 +- .../model/indicator/AverageTest.java | 6 +- .../model/indicator/ColdsumtminTest.java | 5 +- .../model/indicator/DayOfYearTest.java | 7 +-- .../model/indicator/DiffOfSumTest.java | 6 +- .../model/indicator/FormulaTest.java | 7 +-- .../model/indicator/FrequencyTest.java | 7 +-- .../model/indicator/IndicatorTest.java | 7 +-- .../model/indicator/MaxWaveLengthTest.java | 21 +++---- .../model/indicator/NumberOfDaysTest.java | 11 ++-- .../model/indicator/NumberOfWavesTest.java | 19 ++---- .../model/indicator/PhaseLengthTest.java | 5 +- .../indicator/PhotothermalQuotientTest.java | 7 +-- .../model/indicator/QuotientTest.java | 7 +-- .../indicators/model/indicator/SumTest.java | 7 +-- 66 files changed, 454 insertions(+), 396 deletions(-) create mode 100644 src/main/java/fr/inrae/agroclim/indicators/exception/ThrowingToDoubleFunction.java diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 119da58a..d4d6140b 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -20,7 +20,7 @@ build_job: stage: build script: - echo "Maven compile started" - - mvn compile + - mvn compile test-compile - ls -lha /usr/bin/tokei - /usr/bin/tokei --version diff --git a/src/main/java/fr/inrae/agroclim/indicators/exception/ErrorMessageException.java b/src/main/java/fr/inrae/agroclim/indicators/exception/ErrorMessageException.java index 0ac0c704..524fb1ac 100644 --- a/src/main/java/fr/inrae/agroclim/indicators/exception/ErrorMessageException.java +++ b/src/main/java/fr/inrae/agroclim/indicators/exception/ErrorMessageException.java @@ -1,5 +1,6 @@ package fr.inrae.agroclim.indicators.exception; +import lombok.Getter; import lombok.RequiredArgsConstructor; /** @@ -17,8 +18,24 @@ public abstract class ErrorMessageException extends Exception { /** * The object with details. */ + @Getter private final ErrorMessage errorMessage; + /** + * Constructor. + * + * @param message The object with details. + * @param cause the cause (which is saved for later retrieval by the + * {@link #getCause()} method). (A {@code null} value is + * permitted, and indicates that the cause is nonexistent or + * unknown.) + + */ + public ErrorMessageException(final ErrorMessage message, final Throwable cause) { + super("", cause); + this.errorMessage = message; + } + @Override public final String getMessage() { return errorMessage.getMessage(); diff --git a/src/main/java/fr/inrae/agroclim/indicators/exception/FunctionalException.java b/src/main/java/fr/inrae/agroclim/indicators/exception/FunctionalException.java index e36e2d1d..831c2c77 100644 --- a/src/main/java/fr/inrae/agroclim/indicators/exception/FunctionalException.java +++ b/src/main/java/fr/inrae/agroclim/indicators/exception/FunctionalException.java @@ -18,7 +18,10 @@ package fr.inrae.agroclim.indicators.exception; /** * For Indicator, Evaluation and AggregationFunction. + * + * @deprecated Use {@link IndicatorsException}. */ +@Deprecated public class FunctionalException extends AbstractException { /** * UUID for Serializable. diff --git a/src/main/java/fr/inrae/agroclim/indicators/exception/IndicatorsException.java b/src/main/java/fr/inrae/agroclim/indicators/exception/IndicatorsException.java index b910e449..5d143c17 100644 --- a/src/main/java/fr/inrae/agroclim/indicators/exception/IndicatorsException.java +++ b/src/main/java/fr/inrae/agroclim/indicators/exception/IndicatorsException.java @@ -28,4 +28,17 @@ public class IndicatorsException extends ErrorMessageException { super(new ErrorMessage("fr.inrae.agroclim.indicators.resources.messages", errorType, List.of(arguments))); } + /** + * Constructor. + * + * @param errorType Error type. + * @param arguments Arguments for the message. + * @param cause the cause (which is saved for later retrieval by the + * {@link #getCause()} method). (A {@code null} value is + * permitted, and indicates that the cause is nonexistent or + * unknown.) + */ + public IndicatorsException(final ErrorType errorType, final Throwable cause, final Serializable... arguments) { + super(new ErrorMessage("fr.inrae.agroclim.indicators.resources.messages", errorType, List.of(arguments)), cause); + } } diff --git a/src/main/java/fr/inrae/agroclim/indicators/exception/TechnicalException.java b/src/main/java/fr/inrae/agroclim/indicators/exception/TechnicalException.java index 6915c8af..ecee955e 100644 --- a/src/main/java/fr/inrae/agroclim/indicators/exception/TechnicalException.java +++ b/src/main/java/fr/inrae/agroclim/indicators/exception/TechnicalException.java @@ -18,7 +18,10 @@ package fr.inrae.agroclim.indicators.exception; /** * For XMLUtils. + * + * @deprecated Use {@link IndicatorsException}. */ +@Deprecated public class TechnicalException extends AbstractException { /** diff --git a/src/main/java/fr/inrae/agroclim/indicators/exception/ThrowingToDoubleFunction.java b/src/main/java/fr/inrae/agroclim/indicators/exception/ThrowingToDoubleFunction.java new file mode 100644 index 00000000..b96cf2c4 --- /dev/null +++ b/src/main/java/fr/inrae/agroclim/indicators/exception/ThrowingToDoubleFunction.java @@ -0,0 +1,40 @@ +package fr.inrae.agroclim.indicators.exception; + +import java.util.function.ToDoubleFunction; + +/** + * ToDoubleFunction to handle exceptions. + * + * Inspired by https://www.baeldung.com/java-lambda-exceptions. + * + * @author Olivier Maury + * @param <T> the type of the input to the function + * @param <E> the type of the thrown exception + */ +@FunctionalInterface +public interface ThrowingToDoubleFunction<T, E extends Exception> { + + /** + * Applies this function to the given argument. + * + * @param value the function argument + * @return the function result + * @throws E exception + */ + double applyAsDouble(T value) throws E; + + /** + * @param <U> the type of the input to the function + * @param throwingFunction the function + * @return function which throws checked exception + */ + static <U> ToDoubleFunction wrap(final ThrowingToDoubleFunction<U, Exception> throwingFunction) { + return (ToDoubleFunction) (Object value) -> { + try { + return throwingFunction.applyAsDouble((U) value); + } catch (final Exception ex) { + throw new RuntimeException(ex); + } + }; + } +} diff --git a/src/main/java/fr/inrae/agroclim/indicators/exception/type/ComputationErrorType.java b/src/main/java/fr/inrae/agroclim/indicators/exception/type/ComputationErrorType.java index 98523c07..c940efa6 100644 --- a/src/main/java/fr/inrae/agroclim/indicators/exception/type/ComputationErrorType.java +++ b/src/main/java/fr/inrae/agroclim/indicators/exception/type/ComputationErrorType.java @@ -3,6 +3,7 @@ package fr.inrae.agroclim.indicators.exception.type; import fr.inrae.agroclim.indicators.exception.ErrorCategory; import fr.inrae.agroclim.indicators.exception.ErrorType; import fr.inrae.agroclim.indicators.exception.IndicatorsErrorCategory; +import fr.inrae.agroclim.indicators.model.indicator.CompositeIndicator; import lombok.Getter; import lombok.RequiredArgsConstructor; @@ -14,11 +15,67 @@ public enum ComputationErrorType implements ErrorType { /** * Definition of the indicator is not good. */ - WRONG_DEFINITION(null, "01"), + WRONG_DEFINITION(null, "001"), + /** + * When an indicator fails to compute. + */ + COMPUTATION(null, "100"), + /** + * When an indicator in a {@link CompositeIndicator} fails to compute. + */ + COMPOSITE_COMPUTATION(COMPUTATION, "101"), /** * Criteria should be NoCriteria or SimpleCriteria. */ - CRITERIA_ISNT_NOCRITERIA_SIMPLECRITERIA(WRONG_DEFINITION, "02"); + CRITERIA_ISNT_NOCRITERIA_SIMPLECRITERIA(WRONG_DEFINITION, "002"), + /** + * Criteria should not be null. + */ + CRITERIA_NULL(WRONG_DEFINITION, "003"), + /** + * Daily data must not be null. + */ + DATA_NULL(COMPUTATION, "113"), + /** + * Dividend indicator should never be null. + */ + QUOTIENT_DIVIDEND_NULL(WRONG_DEFINITION, "005"), + /** + * Computation of dividend failed. + */ + QUOTIENT_DIVIDEND_EXCEPTION(COMPUTATION, "110"), + /** + * Computation of divisor failed. + */ + QUOTIENT_DIVISOR_EXCEPTION(COMPUTATION, "111"), + /** + * Cannot compute quotient as result of divisor is zero. + */ + QUOTIENT_DIVISOR_ZERO(COMPUTATION, "112"), + /** + * Divisor indicator should never be null. + */ + QUOTIENT_DIVISOR_NULL(WRONG_DEFINITION, "006"), + FORMULA(null, "200"), + FORMULA_AGGREGATION_NULL(FORMULA, "211"), + FORMULA_EXPRESSION_NULL(FORMULA, "221"), + FORMULA_EXPRESSION_BLANK(FORMULA, "222"), + FORMULA_EXPRESSION_PARENTHESIS(FORMULA, "223"), + FORMULA_EXPRESSION_PARSING(FORMULA, "224"), + FORMULA_FUNCTION_UNKNOWN(FORMULA, "231"), + FORMULA_VARIABLE_UNDEFINED(FORMULA, "241"), + /** + * Threshold must not be null. + */ + THRESHOLD_NULL(WRONG_DEFINITION, "004"), + /** + * Variable must not be null. + */ + VARIABLE_NAME_NULL(WRONG_DEFINITION, "007"), + /** + * Value for the variable must not be null. + */ + VARIABLE_VALUE_NULL(COMPUTATION, "114"); /** * Parent refers to the resource part. diff --git a/src/main/java/fr/inrae/agroclim/indicators/exception/type/ResourceErrorType.java b/src/main/java/fr/inrae/agroclim/indicators/exception/type/ResourceErrorType.java index aef77fda..6e1f6074 100644 --- a/src/main/java/fr/inrae/agroclim/indicators/exception/type/ResourceErrorType.java +++ b/src/main/java/fr/inrae/agroclim/indicators/exception/type/ResourceErrorType.java @@ -12,75 +12,76 @@ public enum ResourceErrorType implements ErrorType { /** * Climate, topic. */ - CLIMATE("01", null, "resource.climatic"), + CLIMATE("100", null, "resource.climatic"), /** * No climate data. */ - CLIMATE_EMPTY("02", CLIMATE, "empty"), + CLIMATE_EMPTY("110", CLIMATE, "empty"), + CLIMATE_EMPTY_FOR_PHASE("111", CLIMATE_EMPTY, "for.phase"), /** * Not enough data. */ - CLIMATE_SIZE_WRONG("03", CLIMATE, "size.wrong"), + CLIMATE_SIZE_WRONG("101", CLIMATE, "size.wrong"), /** * Years of climate, topic. */ - CLIMATIC_YEARS("04", null, "resource.climatic.years"), + CLIMATIC_YEARS("120", null, "resource.climatic.years"), /** * No years of climate. */ - CLIMATE_YEARS_EMPTY("05", CLIMATIC_YEARS, "empty"), + CLIMATE_YEARS_EMPTY("121", CLIMATIC_YEARS, "empty"), /** * Not enough data. */ - CLIMATE_YEARS_MISSING("06", CLIMATIC_YEARS, "missing"), + CLIMATE_YEARS_MISSING("122", CLIMATIC_YEARS, "missing"), /** * Phenology, topic. */ - PHENO("07", null, "resource.pheno"), + PHENO("200", null, "resource.pheno"), /** * No phenological data. */ - PHENO_EMPTY("08", PHENO, "empty"), + PHENO_EMPTY("201", PHENO, "empty"), /** * Years of phenology, topic. */ - PHENO_YEARS("09", null, "resource.pheno.years"), + PHENO_YEARS("210", null, "resource.pheno.years"), /** * No years of phenology. */ - PHENO_YEARS_EMPTY("10", PHENO_YEARS, "empty"), + PHENO_YEARS_EMPTY("211", PHENO_YEARS, "empty"), /** * Not enough data. */ - PHENO_YEARS_MISSING("11", PHENO_YEARS, "missing"), + PHENO_YEARS_MISSING("212", PHENO_YEARS, "missing"), /** * Resource in general, topic. */ - RESOURCE("12", null, "resource"), + RESOURCE("001", null, "resource"), /** * Setting not set. */ - RESOURCE_CROPDEVELOPMENT_YEARS("13", RESOURCE, "cropdevelopmentyears.null"), + RESOURCE_CROPDEVELOPMENT_YEARS("002", RESOURCE, "cropdevelopmentyears.null"), /** * Soil, topic. */ - SOIL("14", null, "resource.soil"), + SOIL("300", null, "resource.soil"), /** * Not enough data. */ - SOIL_SIZE_WRONG("15", SOIL, "size.wrong"), + SOIL_SIZE_WRONG("301", SOIL, "size.wrong"), /** * Variables, topic. */ - VARIABLES("16", null, "resource.variables"), + VARIABLES("400", null, "resource.variables"), /** * No variable. */ - VARIABLES_EMPTY("17", VARIABLES, "empty"), + VARIABLES_EMPTY("401", VARIABLES, "empty"), /** * No variale. */ - VARIABLES_MISSING("18", VARIABLES, "missing"); + VARIABLES_MISSING("402", VARIABLES, "missing"); /** * Key for Resource/I18nResource. */ diff --git a/src/main/java/fr/inrae/agroclim/indicators/model/Evaluation.java b/src/main/java/fr/inrae/agroclim/indicators/model/Evaluation.java index 57d1497e..2648642c 100644 --- a/src/main/java/fr/inrae/agroclim/indicators/model/Evaluation.java +++ b/src/main/java/fr/inrae/agroclim/indicators/model/Evaluation.java @@ -26,14 +26,13 @@ import java.util.HashSet; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; -import java.util.Locale; import java.util.Map; import java.util.Objects; import java.util.Set; import java.util.stream.Collectors; -import fr.inrae.agroclim.indicators.exception.FunctionalException; -import fr.inrae.agroclim.indicators.exception.TechnicalException; +import fr.inrae.agroclim.indicators.exception.IndicatorsException; +import fr.inrae.agroclim.indicators.exception.type.ResourceErrorType; import fr.inrae.agroclim.indicators.model.data.ResourceManager; import fr.inrae.agroclim.indicators.model.data.Variable; import fr.inrae.agroclim.indicators.model.data.Variable.Type; @@ -53,7 +52,6 @@ import fr.inrae.agroclim.indicators.model.indicator.listener.IndicatorEvent; import fr.inrae.agroclim.indicators.model.result.EvaluationResult; import fr.inrae.agroclim.indicators.model.result.IndicatorResult; import fr.inrae.agroclim.indicators.model.result.PhaseResult; -import fr.inrae.agroclim.indicators.resources.I18n; import fr.inrae.agroclim.indicators.resources.Messages; import fr.inrae.agroclim.indicators.util.DateUtils; import fr.inrae.agroclim.indicators.util.StageUtils; @@ -302,12 +300,10 @@ public final class Evaluation extends CompositeIndicator { /** * Compute indicator results. * - * @throws TechnicalException - * from Indicator.compute() - * @throws FunctionalException + * @throws IndicatorsException * from Indicator.compute() */ - public void compute() throws TechnicalException, FunctionalException { + public void compute() throws IndicatorsException { LOGGER.trace("start computing evaluation \"" + getName() + "\""); fireIndicatorEvent(IndicatorEvent.Type.COMPUTE_START.event(this)); @@ -319,12 +315,10 @@ public final class Evaluation extends CompositeIndicator { throw new RuntimeException("Phase list is empty!"); } if (resourceManager.getClimaticResource().isEmpty()) { - throw new FunctionalException( - "There is not any climatic daily data!"); + throw new IndicatorsException(ResourceErrorType.CLIMATE_EMPTY); } if (resourceManager.getPhenologicalResource().isEmpty()) { - throw new FunctionalException( - "There is not any phenological data !"); + throw new IndicatorsException(ResourceErrorType.PHENO_EMPTY); } clearResults(); @@ -408,26 +402,21 @@ public final class Evaluation extends CompositeIndicator { final ClimaticResource climaticData = resourceManager .getClimaticResource().getClimaticDataByPhaseAndYear(startDate, endDate); if (climaticData.isEmpty()) { - final I18n i18n = new I18n("fr.inrae.agroclim.indicators.resources.messages", Locale.getDefault()); - final StringBuilder sb = new StringBuilder(); - sb.append(i18n.format("error.climate.missing", - startStageName, endStageName, startStage, endStage, dateYear)); if (resourceManager.getClimaticResource().isEmpty()) { - sb.append(i18n.format("error.climate.no.data")); - throw new RuntimeException(sb.toString()); - } else { - final int yearToSearch = dateYear; - final List<ClimaticDailyData> ddataList = resourceManager.getClimaticResource().getData() - .stream().filter(f -> f.getYear() == yearToSearch).collect(Collectors.toList()); - - final ClimaticDailyData startData = ddataList.get(0); - final ClimaticDailyData endData = ddataList.get(ddataList.size() - 1); - - sb.append(i18n.format("error.climate.dates", dateYear, - startData.getYear() + "-" + startData.getMonth() + "-" + startData.getDay(), - endData.getYear() + "-" + endData.getMonth() + "-" + endData.getDay())); + throw new IndicatorsException(ResourceErrorType.CLIMATE_EMPTY); } - throw new FunctionalException(sb.toString()); + final int yearToSearch = dateYear; + final List<ClimaticDailyData> ddataList = resourceManager.getClimaticResource().getData() + .stream().filter(f -> f.getYear() == yearToSearch).collect(Collectors.toList()); + + final ClimaticDailyData startData = ddataList.get(0); + final ClimaticDailyData endData = ddataList.get(ddataList.size() - 1); + + throw new IndicatorsException(ResourceErrorType.CLIMATE_EMPTY_FOR_PHASE, + startStageName, endStageName, startStage, endStage, dateYear, // + startData.getYear() + "-" + startData.getMonth() + "-" + startData.getDay(), // + endData.getYear() + "-" + endData.getMonth() + "-" + endData.getDay() + ); } /* #9451 - En cas de données manquantes, on passe à l'année suivante * Par défaut, le résultat de l'évaluation du couple phase/année vaut NA (null). @@ -459,9 +448,9 @@ public final class Evaluation extends CompositeIndicator { * Pour chaque année, Pour chaque phase, valeurs.onIndicatorAdd(valeur phase * p, année n); Fin pour aggregation(valeurs); Fin pour; * - * @throws FunctionalException raised by AggregationFunction.aggregate() + * @throws IndicatorsException raised by AggregationFunction.aggregate() */ - private void computeFaisability() throws FunctionalException { + private void computeFaisability() throws IndicatorsException { LOGGER.traceEntry(); if (getType() == EvaluationType.WITHOUT_AGGREGATION) { return; @@ -831,7 +820,7 @@ public final class Evaluation extends CompositeIndicator { getPhases().forEach(phase -> values.put(phase.getId(), 1.)); try { getAggregationFunction().aggregate(values); - } catch (final FunctionalException ex) { + } catch (final IndicatorsException ex) { LOGGER.info("Invalid aggregation: {}", ex.getLocalizedMessage()); return false; } diff --git a/src/main/java/fr/inrae/agroclim/indicators/model/JEXLFormula.java b/src/main/java/fr/inrae/agroclim/indicators/model/JEXLFormula.java index c3c52afe..98c5b2be 100644 --- a/src/main/java/fr/inrae/agroclim/indicators/model/JEXLFormula.java +++ b/src/main/java/fr/inrae/agroclim/indicators/model/JEXLFormula.java @@ -35,7 +35,8 @@ import org.apache.commons.jexl3.JexlFeatures; import org.apache.commons.jexl3.JexlScript; import org.apache.commons.jexl3.MapContext; -import fr.inrae.agroclim.indicators.exception.FunctionalException; +import fr.inrae.agroclim.indicators.exception.IndicatorsException; +import fr.inrae.agroclim.indicators.exception.type.ComputationErrorType; import fr.inrae.agroclim.indicators.model.criteria.FormulaCriteria; import fr.inrae.agroclim.indicators.model.data.Variable; import fr.inrae.agroclim.indicators.model.function.aggregation.MathMethod; @@ -119,15 +120,15 @@ public class JEXLFormula { * @param values variable name ⮕ value * @param clazz result class * @return The result of this evaluation - * @throws fr.inrae.agroclim.indicators.exception.FunctionalException on any error + * @throws IndicatorsException on any error */ @SuppressWarnings("unchecked") - public <T> T evaluate(final Map<String, Double> values, final Class<T> clazz) throws FunctionalException { + public <T> T evaluate(final Map<String, Double> values, final Class<T> clazz) throws IndicatorsException { try { if (getExpression() == null) { - throw new FunctionalException(errorMessage("expression.null")); - } else if (getExpression().isEmpty()) { - throw new FunctionalException(errorMessage("expression.empty")); + throw new IndicatorsException(ComputationErrorType.FORMULA_EXPRESSION_NULL); + } else if (getExpression().isBlank()) { + throw new IndicatorsException(ComputationErrorType.FORMULA_EXPRESSION_BLANK); } final JexlExpression exp = jexl.createExpression(getExpression()); @@ -141,18 +142,18 @@ public class JEXLFormula { context.set(text, values.get(key)); }); return (T) exp.evaluate(context); - } catch (final JexlException.Variable variable) { - throw new FunctionalException(errorMessage("variable.undefined", getExpression(), variable.getVariable()), - variable); - } catch (final JexlException.Method method) { - throw new FunctionalException(errorMessage("function.unknown", getExpression(), method.getMethod()), - method); - } catch (final JexlException.Parsing parsing) { - throw new FunctionalException(errorMessage("expression.parsing", getExpression()), parsing); - } catch (final JexlException.Tokenization token) { - throw new FunctionalException(errorMessage("expression.parenthesis", getExpression()), token); - } catch (final JexlException e) { - throw new FunctionalException(errorMessage("execution", getExpression()) + e.getLocalizedMessage(), e); + } catch (final JexlException.Variable ex) { + throw new IndicatorsException(ComputationErrorType.FORMULA_VARIABLE_UNDEFINED, ex, getExpression(), + ex.getVariable()); + } catch (final JexlException.Method ex) { + throw new IndicatorsException(ComputationErrorType.FORMULA_FUNCTION_UNKNOWN, ex, getExpression(), + ex.getMethod()); + } catch (final JexlException.Parsing ex) { + throw new IndicatorsException(ComputationErrorType.FORMULA_EXPRESSION_PARSING, ex, getExpression()); + } catch (final JexlException.Tokenization ex) { + throw new IndicatorsException(ComputationErrorType.FORMULA_EXPRESSION_PARENTHESIS, ex, getExpression()); + } catch (final JexlException ex) { + throw new IndicatorsException(ComputationErrorType.FORMULA, ex, getExpression()); } } diff --git a/src/main/java/fr/inrae/agroclim/indicators/model/Quantifiable.java b/src/main/java/fr/inrae/agroclim/indicators/model/Quantifiable.java index 44472bdd..6eca2881 100644 --- a/src/main/java/fr/inrae/agroclim/indicators/model/Quantifiable.java +++ b/src/main/java/fr/inrae/agroclim/indicators/model/Quantifiable.java @@ -16,8 +16,7 @@ */ package fr.inrae.agroclim.indicators.model; -import fr.inrae.agroclim.indicators.exception.FunctionalException; -import fr.inrae.agroclim.indicators.exception.TechnicalException; +import fr.inrae.agroclim.indicators.exception.IndicatorsException; import fr.inrae.agroclim.indicators.model.data.DailyData; import fr.inrae.agroclim.indicators.model.data.Resource; @@ -34,11 +33,7 @@ public interface Quantifiable { * @param data * resource of daily data * @return single result for resource of daily data - * @throws TechnicalException - * technical exception - * @throws FunctionalException - * functional exception + * @throws IndicatorsException */ - Double compute(Resource<? extends DailyData> data) - throws TechnicalException, FunctionalException; + Double compute(Resource<? extends DailyData> data) throws IndicatorsException; } diff --git a/src/main/java/fr/inrae/agroclim/indicators/model/criteria/ComparisonCriteria.java b/src/main/java/fr/inrae/agroclim/indicators/model/criteria/ComparisonCriteria.java index 453b4055..5779acb8 100644 --- a/src/main/java/fr/inrae/agroclim/indicators/model/criteria/ComparisonCriteria.java +++ b/src/main/java/fr/inrae/agroclim/indicators/model/criteria/ComparisonCriteria.java @@ -18,7 +18,8 @@ */ package fr.inrae.agroclim.indicators.model.criteria; -import fr.inrae.agroclim.indicators.exception.TechnicalException; +import fr.inrae.agroclim.indicators.exception.IndicatorsException; +import fr.inrae.agroclim.indicators.exception.type.ComputationErrorType; import fr.inrae.agroclim.indicators.model.Parameter; import fr.inrae.agroclim.indicators.model.data.DailyData; import fr.inrae.agroclim.indicators.model.data.Resource; @@ -99,9 +100,10 @@ public final class ComparisonCriteria extends Criteria { } @Override - public boolean eval(final DailyData dailydata) throws TechnicalException { + public boolean eval(final DailyData dailydata) throws IndicatorsException { if (relationalOperator == null) { - throw new RuntimeException("The relational operator must be set!"); + throw new IndicatorsException(ComputationErrorType.WRONG_DEFINITION, + "The relational operator must be set!"); } if (dailydata == null) { return false; diff --git a/src/main/java/fr/inrae/agroclim/indicators/model/criteria/CompositeCriteria.java b/src/main/java/fr/inrae/agroclim/indicators/model/criteria/CompositeCriteria.java index 37bb407f..3f09a9f9 100644 --- a/src/main/java/fr/inrae/agroclim/indicators/model/criteria/CompositeCriteria.java +++ b/src/main/java/fr/inrae/agroclim/indicators/model/criteria/CompositeCriteria.java @@ -16,12 +16,13 @@ */ package fr.inrae.agroclim.indicators.model.criteria; +import fr.inrae.agroclim.indicators.exception.IndicatorsException; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; -import fr.inrae.agroclim.indicators.exception.TechnicalException; +import fr.inrae.agroclim.indicators.exception.type.ComputationErrorType; import fr.inrae.agroclim.indicators.model.Parameter; import fr.inrae.agroclim.indicators.model.data.DailyData; import fr.inrae.agroclim.indicators.model.data.Resource; @@ -87,10 +88,9 @@ public final class CompositeCriteria extends Criteria { } @Override - public boolean eval(final DailyData dailyData) - throws TechnicalException { + public boolean eval(final DailyData dailyData) throws IndicatorsException { if (logicalOperator == null) { - throw new RuntimeException("The logical operator must be set!"); + throw new IndicatorsException(ComputationErrorType.WRONG_DEFINITION, "The logical operator must be set!"); } switch (logicalOperator) { case AND: @@ -125,11 +125,10 @@ public final class CompositeCriteria extends Criteria { * @param data * climatic data * @return formula - * @throws TechnicalException + * @throws IndicatorsException * exception while getting data */ - public String getFormula(final ClimaticDailyData data) - throws TechnicalException { + public String getFormula(final ClimaticDailyData data) throws IndicatorsException { StringBuilder sb = new StringBuilder(); boolean first = true; for (final Criteria aCriteria : criteria) { diff --git a/src/main/java/fr/inrae/agroclim/indicators/model/criteria/Criteria.java b/src/main/java/fr/inrae/agroclim/indicators/model/criteria/Criteria.java index 4e368155..8934fd79 100644 --- a/src/main/java/fr/inrae/agroclim/indicators/model/criteria/Criteria.java +++ b/src/main/java/fr/inrae/agroclim/indicators/model/criteria/Criteria.java @@ -16,6 +16,7 @@ */ package fr.inrae.agroclim.indicators.model.criteria; +import fr.inrae.agroclim.indicators.exception.IndicatorsException; import java.beans.PropertyChangeListener; import java.beans.PropertyChangeSupport; import java.io.Serializable; @@ -28,7 +29,6 @@ import javax.xml.bind.annotation.XmlElementWrapper; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlTransient; -import fr.inrae.agroclim.indicators.exception.TechnicalException; import fr.inrae.agroclim.indicators.model.Computable; import fr.inrae.agroclim.indicators.model.HasParameters; import fr.inrae.agroclim.indicators.model.Parameter; @@ -114,11 +114,10 @@ Computable, HasParameters, Serializable, UseVariables { * @param data * data to compare * @return comparison result - * @throws TechnicalException + * @throws IndicatorsException * exception during evaluation */ - public abstract boolean eval(DailyData data) - throws TechnicalException; + public abstract boolean eval(DailyData data) throws IndicatorsException; /** * @param indent diff --git a/src/main/java/fr/inrae/agroclim/indicators/model/criteria/FormulaCriteria.java b/src/main/java/fr/inrae/agroclim/indicators/model/criteria/FormulaCriteria.java index 29c23fd4..02c5a31d 100644 --- a/src/main/java/fr/inrae/agroclim/indicators/model/criteria/FormulaCriteria.java +++ b/src/main/java/fr/inrae/agroclim/indicators/model/criteria/FormulaCriteria.java @@ -24,15 +24,15 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Objects; import java.util.Set; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlType; -import fr.inrae.agroclim.indicators.exception.FunctionalException; -import fr.inrae.agroclim.indicators.exception.TechnicalException; +import fr.inrae.agroclim.indicators.exception.IndicatorsException; +import fr.inrae.agroclim.indicators.exception.type.ComputationErrorType; +import fr.inrae.agroclim.indicators.exception.type.ResourceErrorType; import fr.inrae.agroclim.indicators.model.ExpressionParameter; import fr.inrae.agroclim.indicators.model.JEXLFormula; import fr.inrae.agroclim.indicators.model.Parameter; @@ -143,9 +143,13 @@ public final class FormulaCriteria extends Criteria { } @Override - public boolean eval(final DailyData data) throws TechnicalException { - Objects.requireNonNull(expression, "expression must not be null!"); - Objects.requireNonNull(data, "Resource data must not be null!"); + public boolean eval(final DailyData data) throws IndicatorsException { + if (expression == null) { + throw new IndicatorsException(ComputationErrorType.FORMULA_EXPRESSION_NULL); + } + if (data == null) { + throw new IndicatorsException(ResourceErrorType.CLIMATE_EMPTY); + } formula.setExpression(expression); final Map<String, Double> values = new HashMap<>(); getVariables().forEach(variable -> values.put(variable.name(), data.getValue(variable))); @@ -157,8 +161,8 @@ public final class FormulaCriteria extends Criteria { } try { return formula.evaluate(values, Boolean.class); - } catch (final FunctionalException ex) { - throw new TechnicalException("Failed to evaluate the criteria: " + ex.getLocalizedMessage(), ex); + } catch (final IndicatorsException ex) { + throw new IndicatorsException(ComputationErrorType.FORMULA, ex, "Failed to evaluate the criteria."); } } diff --git a/src/main/java/fr/inrae/agroclim/indicators/model/criteria/NoCriteria.java b/src/main/java/fr/inrae/agroclim/indicators/model/criteria/NoCriteria.java index 98660e25..d6c88efe 100644 --- a/src/main/java/fr/inrae/agroclim/indicators/model/criteria/NoCriteria.java +++ b/src/main/java/fr/inrae/agroclim/indicators/model/criteria/NoCriteria.java @@ -18,13 +18,13 @@ */ package fr.inrae.agroclim.indicators.model.criteria; +import fr.inrae.agroclim.indicators.exception.IndicatorsException; import java.util.Map; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlType; -import fr.inrae.agroclim.indicators.exception.TechnicalException; import fr.inrae.agroclim.indicators.model.Parameter; import fr.inrae.agroclim.indicators.model.data.DailyData; import fr.inrae.agroclim.indicators.util.Doublet; @@ -59,7 +59,7 @@ public final class NoCriteria extends VariableCriteria { } @Override - public boolean eval(final DailyData data) throws TechnicalException { + public boolean eval(final DailyData data) throws IndicatorsException { return true; } diff --git a/src/main/java/fr/inrae/agroclim/indicators/model/criteria/SimpleCriteria.java b/src/main/java/fr/inrae/agroclim/indicators/model/criteria/SimpleCriteria.java index 4c59c441..33703356 100644 --- a/src/main/java/fr/inrae/agroclim/indicators/model/criteria/SimpleCriteria.java +++ b/src/main/java/fr/inrae/agroclim/indicators/model/criteria/SimpleCriteria.java @@ -16,6 +16,7 @@ */ package fr.inrae.agroclim.indicators.model.criteria; +import fr.inrae.agroclim.indicators.exception.IndicatorsException; import java.util.HashMap; import java.util.Map; import java.util.Objects; @@ -25,7 +26,6 @@ import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlTransient; import javax.xml.bind.annotation.XmlType; -import fr.inrae.agroclim.indicators.exception.TechnicalException; import fr.inrae.agroclim.indicators.model.Parameter; import fr.inrae.agroclim.indicators.model.data.DailyData; import fr.inrae.agroclim.indicators.model.data.Variable; @@ -139,7 +139,7 @@ public final class SimpleCriteria extends VariableCriteria { } @Override - public boolean eval(final DailyData dailydata) throws TechnicalException { + public boolean eval(final DailyData dailydata) throws IndicatorsException { if (dailydata == null) { return false; } @@ -168,11 +168,10 @@ public final class SimpleCriteria extends VariableCriteria { * @param data * climatic data * @return formula - * @throws TechnicalException + * @throws IndicatorsException * exception while getting data */ - public String getFormula(final ClimaticDailyData data) - throws TechnicalException { + public String getFormula(final ClimaticDailyData data) throws IndicatorsException { final StringBuilder sb = new StringBuilder(); sb.append(getValueOf(data)); sb.append(" "); diff --git a/src/main/java/fr/inrae/agroclim/indicators/model/criteria/VariableCriteria.java b/src/main/java/fr/inrae/agroclim/indicators/model/criteria/VariableCriteria.java index 0f9c14a5..5e58c4f8 100644 --- a/src/main/java/fr/inrae/agroclim/indicators/model/criteria/VariableCriteria.java +++ b/src/main/java/fr/inrae/agroclim/indicators/model/criteria/VariableCriteria.java @@ -18,7 +18,8 @@ */ package fr.inrae.agroclim.indicators.model.criteria; -import java.util.HashSet; +import fr.inrae.agroclim.indicators.exception.IndicatorsException; +import fr.inrae.agroclim.indicators.exception.type.ComputationErrorType; import java.util.Objects; import java.util.Set; @@ -67,25 +68,25 @@ public abstract class VariableCriteria extends Criteria { * * @param data climatic data * @return value of "variable" + * @throws IndicatorsException in case of wrong definition or while getting value */ - public final double getValueOf(final DailyData data) { + public final double getValueOf(final DailyData data) throws IndicatorsException { if (data == null) { - throw new IllegalArgumentException("DailyData is null!"); + throw new IndicatorsException(ComputationErrorType.DATA_NULL); } if (variable == null) { - throw new NullPointerException("variable is null!"); + throw new IndicatorsException(ComputationErrorType.VARIABLE_NAME_NULL); } - if (data.getValue(variable) == null) { - throw new NullPointerException("At " + data.getDate() + ", " + variable + " is null!"); + final var value = data.getValue(variable); + if (value == null) { + throw new IndicatorsException(ComputationErrorType.VARIABLE_VALUE_NULL, data.getDate(), variable); } - return data.getValue(variable); + return value; } @Override public final Set<Variable> getVariables() { - final Set<Variable> variables = new HashSet<>(); - variables.add(variable); - return variables; + return Set.of(variable); } /** diff --git a/src/main/java/fr/inrae/agroclim/indicators/model/function/aggregation/AggregationFunction.java b/src/main/java/fr/inrae/agroclim/indicators/model/function/aggregation/AggregationFunction.java index 3498f290..0816bf08 100644 --- a/src/main/java/fr/inrae/agroclim/indicators/model/function/aggregation/AggregationFunction.java +++ b/src/main/java/fr/inrae/agroclim/indicators/model/function/aggregation/AggregationFunction.java @@ -23,7 +23,7 @@ import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlAttribute; -import fr.inrae.agroclim.indicators.exception.FunctionalException; +import fr.inrae.agroclim.indicators.exception.IndicatorsException; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.Setter; @@ -56,11 +56,10 @@ public abstract class AggregationFunction implements Serializable { * @param values * values to use for aggregation * @return aggregated value - * @throws FunctionalException + * @throws IndicatorsException * exception */ - public abstract double aggregate(Map<String, Double> values) - throws FunctionalException; + public abstract double aggregate(Map<String, Double> values) throws IndicatorsException; /** * @return function is valid diff --git a/src/main/java/fr/inrae/agroclim/indicators/model/function/aggregation/JEXLFunction.java b/src/main/java/fr/inrae/agroclim/indicators/model/function/aggregation/JEXLFunction.java index 498d0ee3..1e14519f 100644 --- a/src/main/java/fr/inrae/agroclim/indicators/model/function/aggregation/JEXLFunction.java +++ b/src/main/java/fr/inrae/agroclim/indicators/model/function/aggregation/JEXLFunction.java @@ -6,7 +6,7 @@ import java.util.Map; import javax.xml.bind.annotation.XmlRootElement; -import fr.inrae.agroclim.indicators.exception.FunctionalException; +import fr.inrae.agroclim.indicators.exception.IndicatorsException; import fr.inrae.agroclim.indicators.model.JEXLFormula; import lombok.EqualsAndHashCode; @@ -41,7 +41,7 @@ public final class JEXLFunction extends AggregationFunction { } @Override - public double aggregate(final Map<String, Double> values) throws FunctionalException { + public double aggregate(final Map<String, Double> values) throws IndicatorsException { formula.setExpression(getExpression()); return formula.evaluate(values, Double.class); } diff --git a/src/main/java/fr/inrae/agroclim/indicators/model/indicator/AggregationIndicator.java b/src/main/java/fr/inrae/agroclim/indicators/model/indicator/AggregationIndicator.java index e48ad253..c64f4b32 100644 --- a/src/main/java/fr/inrae/agroclim/indicators/model/indicator/AggregationIndicator.java +++ b/src/main/java/fr/inrae/agroclim/indicators/model/indicator/AggregationIndicator.java @@ -7,9 +7,8 @@ import java.util.stream.DoubleStream; import javax.xml.bind.annotation.XmlElement; -import fr.inrae.agroclim.indicators.exception.FunctionalException; import fr.inrae.agroclim.indicators.exception.IndicatorsException; -import fr.inrae.agroclim.indicators.exception.TechnicalException; +import fr.inrae.agroclim.indicators.exception.ThrowingToDoubleFunction; import fr.inrae.agroclim.indicators.exception.type.ComputationErrorType; import fr.inrae.agroclim.indicators.model.criteria.Criteria; import fr.inrae.agroclim.indicators.model.criteria.NoCriteria; @@ -66,29 +65,36 @@ public abstract class AggregationIndicator extends SimpleIndicatorWithCriteria i } @Override - public final double computeSingleValue(final Resource<? extends DailyData> res) - throws TechnicalException, FunctionalException { + public final double computeSingleValue(final Resource<? extends DailyData> res) throws IndicatorsException { final DoubleStream stream; - if (getCriteria() instanceof final NoCriteria criteria) { - Objects.requireNonNull(criteria.getVariable(), - getId() + ".getCriteria().getVariable() must not be null! " + getVariable()); - // syntax changed to hack Eclipse. - stream = res.getData().stream().mapToDouble(d -> criteria.getValueOf(d)); - } else if (getCriteria() instanceof final SimpleCriteria criteria) { - final Predicate<DailyData> predicate = d -> { - try { - return criteria.eval(d); - } catch (final TechnicalException e) { - return false; - } - }; - stream = res.getData().stream() // - .filter(predicate) // - .mapToDouble(criteria::getValueOf); - } else { - throw new IndicatorsException(ComputationErrorType.CRITERIA_ISNT_NOCRITERIA_SIMPLECRITERIA, getId()); + try { + if (getCriteria() instanceof final NoCriteria criteria) { + Objects.requireNonNull(criteria.getVariable(), + getId() + ".getCriteria().getVariable() must not be null! " + getVariable()); + // syntax changed to hack Eclipse. + stream = res.getData().stream() // + .mapToDouble(ThrowingToDoubleFunction.wrap(criteria::getValueOf)); + } else if (getCriteria() instanceof final SimpleCriteria criteria) { + final Predicate<DailyData> predicate = d -> { + try { + return criteria.eval(d); + } catch (final IndicatorsException e) { + return false; + } + }; + stream = res.getData().stream() // + .filter(predicate) // + .mapToDouble(ThrowingToDoubleFunction.wrap(criteria::getValueOf)); + } else { + throw new IndicatorsException(ComputationErrorType.CRITERIA_ISNT_NOCRITERIA_SIMPLECRITERIA, getId()); + } + return aggregate(stream); + } catch (final RuntimeException ex) { + if (ex.getCause() instanceof IndicatorsException iex) { + throw new IndicatorsException(ComputationErrorType.COMPUTATION, iex); + } + throw ex; } - return aggregate(stream); } @Override diff --git a/src/main/java/fr/inrae/agroclim/indicators/model/indicator/AverageOfDiff.java b/src/main/java/fr/inrae/agroclim/indicators/model/indicator/AverageOfDiff.java index 469c6316..6b5a1dde 100644 --- a/src/main/java/fr/inrae/agroclim/indicators/model/indicator/AverageOfDiff.java +++ b/src/main/java/fr/inrae/agroclim/indicators/model/indicator/AverageOfDiff.java @@ -16,14 +16,13 @@ */ package fr.inrae.agroclim.indicators.model.indicator; +import fr.inrae.agroclim.indicators.exception.IndicatorsException; import java.util.HashSet; import java.util.Set; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlType; -import fr.inrae.agroclim.indicators.exception.FunctionalException; -import fr.inrae.agroclim.indicators.exception.TechnicalException; import fr.inrae.agroclim.indicators.model.data.DailyData; import fr.inrae.agroclim.indicators.model.data.Resource; import fr.inrae.agroclim.indicators.model.data.Variable; @@ -73,8 +72,7 @@ implements Detailable { } @Override - public double computeSingleValue(final Resource<? extends DailyData> res) - throws TechnicalException, FunctionalException { + public double computeSingleValue(final Resource<? extends DailyData> res) throws IndicatorsException { double value = 0; for (final DailyData data : res.getData()) { value += data.getValue(variable1) diff --git a/src/main/java/fr/inrae/agroclim/indicators/model/indicator/CompositeIndicator.java b/src/main/java/fr/inrae/agroclim/indicators/model/indicator/CompositeIndicator.java index 4d395185..1de20057 100644 --- a/src/main/java/fr/inrae/agroclim/indicators/model/indicator/CompositeIndicator.java +++ b/src/main/java/fr/inrae/agroclim/indicators/model/indicator/CompositeIndicator.java @@ -30,8 +30,8 @@ import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlTransient; import javax.xml.bind.annotation.XmlType; -import fr.inrae.agroclim.indicators.exception.FunctionalException; -import fr.inrae.agroclim.indicators.exception.TechnicalException; +import fr.inrae.agroclim.indicators.exception.IndicatorsException; +import fr.inrae.agroclim.indicators.exception.type.ComputationErrorType; import fr.inrae.agroclim.indicators.model.Evaluation; import fr.inrae.agroclim.indicators.model.EvaluationType; import fr.inrae.agroclim.indicators.model.Knowledge; @@ -252,8 +252,7 @@ DataLoadingListener, Detailable, HasDataLoadingListener, Comparable<Indicator> { } @Override - public final Double compute(final Resource<? extends DailyData> climRessource) - throws TechnicalException, FunctionalException { + public final Double compute(final Resource<? extends DailyData> climRessource) throws IndicatorsException { if (climRessource.getYears().isEmpty()) { throw new RuntimeException( String.format( @@ -277,8 +276,8 @@ DataLoadingListener, Detailable, HasDataLoadingListener, Comparable<Indicator> { try { final double value = indicator.compute(climRessource); results.put(indicator.getId(), value); - } catch (FunctionalException | TechnicalException e) { - LOGGER.error("Failed to compute indicator '{}': {}", indicator.getId(), e.getMessage()); + } catch (final IndicatorsException e) { + throw new IndicatorsException(ComputationErrorType.COMPOSITE_COMPUTATION, e, indicator.getId()); } } if (isAggregationNeeded()) { diff --git a/src/main/java/fr/inrae/agroclim/indicators/model/indicator/DayOfYear.java b/src/main/java/fr/inrae/agroclim/indicators/model/indicator/DayOfYear.java index 457b4229..8a5dcb18 100644 --- a/src/main/java/fr/inrae/agroclim/indicators/model/indicator/DayOfYear.java +++ b/src/main/java/fr/inrae/agroclim/indicators/model/indicator/DayOfYear.java @@ -20,8 +20,8 @@ import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlRootElement; -import fr.inrae.agroclim.indicators.exception.FunctionalException; -import fr.inrae.agroclim.indicators.exception.TechnicalException; +import fr.inrae.agroclim.indicators.exception.IndicatorsException; +import fr.inrae.agroclim.indicators.exception.type.ComputationErrorType; import fr.inrae.agroclim.indicators.model.data.DailyData; import fr.inrae.agroclim.indicators.model.data.Resource; import lombok.Getter; @@ -73,10 +73,9 @@ implements Detailable { } @Override - public double computeSingleValue(final Resource<? extends DailyData> data) - throws TechnicalException, FunctionalException { + public double computeSingleValue(final Resource<? extends DailyData> data) throws IndicatorsException { if (first == null) { - throw new FunctionalException("first must not be null!"); + throw new IndicatorsException(ComputationErrorType.WRONG_DEFINITION, "first must not be null"); } double res = 0; boolean resultCriteria; diff --git a/src/main/java/fr/inrae/agroclim/indicators/model/indicator/DiffOfSum.java b/src/main/java/fr/inrae/agroclim/indicators/model/indicator/DiffOfSum.java index 9b7418e3..e0468ca6 100644 --- a/src/main/java/fr/inrae/agroclim/indicators/model/indicator/DiffOfSum.java +++ b/src/main/java/fr/inrae/agroclim/indicators/model/indicator/DiffOfSum.java @@ -26,8 +26,7 @@ import java.util.Set; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlType; -import fr.inrae.agroclim.indicators.exception.FunctionalException; -import fr.inrae.agroclim.indicators.exception.TechnicalException; +import fr.inrae.agroclim.indicators.exception.IndicatorsException; import fr.inrae.agroclim.indicators.model.Knowledge; import fr.inrae.agroclim.indicators.model.Parameter; import fr.inrae.agroclim.indicators.model.data.DailyData; @@ -92,8 +91,7 @@ public final class DiffOfSum extends SimpleIndicator implements Detailable, Indi } @Override - public double computeSingleValue(final Resource<? extends DailyData> res) - throws TechnicalException, FunctionalException { + public double computeSingleValue(final Resource<? extends DailyData> res) throws IndicatorsException { final double sum1 = getSumVariable1().compute(res); final double sum2 = getSumVariable2().compute(res); return sum1 - sum2; diff --git a/src/main/java/fr/inrae/agroclim/indicators/model/indicator/Formula.java b/src/main/java/fr/inrae/agroclim/indicators/model/indicator/Formula.java index 41b36101..bad3df9f 100644 --- a/src/main/java/fr/inrae/agroclim/indicators/model/indicator/Formula.java +++ b/src/main/java/fr/inrae/agroclim/indicators/model/indicator/Formula.java @@ -31,8 +31,9 @@ import java.util.stream.DoubleStream; import javax.xml.bind.annotation.XmlType; -import fr.inrae.agroclim.indicators.exception.FunctionalException; -import fr.inrae.agroclim.indicators.exception.TechnicalException; +import fr.inrae.agroclim.indicators.exception.IndicatorsException; +import fr.inrae.agroclim.indicators.exception.type.ComputationErrorType; +import fr.inrae.agroclim.indicators.exception.type.ResourceErrorType; import fr.inrae.agroclim.indicators.model.ExpressionParameter; import fr.inrae.agroclim.indicators.model.JEXLFormula; import fr.inrae.agroclim.indicators.model.Knowledge; @@ -134,11 +135,14 @@ public final class Formula extends SimpleIndicator implements Detailable { private transient Map<String, Double> parametersValues = new HashMap<>(); @Override - public double computeSingleValue(final Resource<? extends DailyData> res) - throws TechnicalException, FunctionalException { + public double computeSingleValue(final Resource<? extends DailyData> res) throws IndicatorsException { + if (aggregation == null) { + throw new IndicatorsException(ComputationErrorType.FORMULA_AGGREGATION_NULL); + } Objects.requireNonNull(res, "Resource must not be null!"); - Objects.requireNonNull(res.getData(), "Resource data must not be null!"); - Objects.requireNonNull(aggregation, "aggregation must not be null!"); + if (res.getData() == null) { + throw new IndicatorsException(ResourceErrorType.CLIMATE_EMPTY); + } final Set<Variable> dataVariables = getVariables(); final List<Double> computedValues = new ArrayList<>(); for (final DailyData data : res.getData()) { diff --git a/src/main/java/fr/inrae/agroclim/indicators/model/indicator/Frequency.java b/src/main/java/fr/inrae/agroclim/indicators/model/indicator/Frequency.java index 2fc65a2d..30d8e437 100644 --- a/src/main/java/fr/inrae/agroclim/indicators/model/indicator/Frequency.java +++ b/src/main/java/fr/inrae/agroclim/indicators/model/indicator/Frequency.java @@ -22,8 +22,7 @@ import java.util.Set; import javax.xml.bind.annotation.XmlRootElement; -import fr.inrae.agroclim.indicators.exception.FunctionalException; -import fr.inrae.agroclim.indicators.exception.TechnicalException; +import fr.inrae.agroclim.indicators.exception.IndicatorsException; import fr.inrae.agroclim.indicators.model.Knowledge; import fr.inrae.agroclim.indicators.model.Parameter; import fr.inrae.agroclim.indicators.model.data.DailyData; @@ -71,8 +70,7 @@ public final class Frequency extends SimpleIndicator implements Detailable { } @Override - public double computeSingleValue(final Resource<? extends DailyData> data) - throws TechnicalException, FunctionalException { + public double computeSingleValue(final Resource<? extends DailyData> data) throws IndicatorsException { final double cent = 100.; final int days = data.getData().size(); return numberOfDays.compute(data) * cent / days; diff --git a/src/main/java/fr/inrae/agroclim/indicators/model/indicator/InjectedParameter.java b/src/main/java/fr/inrae/agroclim/indicators/model/indicator/InjectedParameter.java index 778617d9..8ac93282 100644 --- a/src/main/java/fr/inrae/agroclim/indicators/model/indicator/InjectedParameter.java +++ b/src/main/java/fr/inrae/agroclim/indicators/model/indicator/InjectedParameter.java @@ -30,8 +30,7 @@ import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlType; -import fr.inrae.agroclim.indicators.exception.FunctionalException; -import fr.inrae.agroclim.indicators.exception.TechnicalException; +import fr.inrae.agroclim.indicators.exception.IndicatorsException; import fr.inrae.agroclim.indicators.model.Knowledge; import fr.inrae.agroclim.indicators.model.Parameter; import fr.inrae.agroclim.indicators.model.data.DailyData; @@ -77,8 +76,7 @@ public final class InjectedParameter extends SimpleIndicator { private Double parameterValue; @Override - public double computeSingleValue(final Resource<? extends DailyData> data) - throws TechnicalException, FunctionalException { + public double computeSingleValue(final Resource<? extends DailyData> data) throws IndicatorsException { if (parameterValue == null) { return 0; } diff --git a/src/main/java/fr/inrae/agroclim/indicators/model/indicator/MaxWaveLength.java b/src/main/java/fr/inrae/agroclim/indicators/model/indicator/MaxWaveLength.java index fa816879..dca5dd74 100644 --- a/src/main/java/fr/inrae/agroclim/indicators/model/indicator/MaxWaveLength.java +++ b/src/main/java/fr/inrae/agroclim/indicators/model/indicator/MaxWaveLength.java @@ -20,8 +20,8 @@ import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlRootElement; -import fr.inrae.agroclim.indicators.exception.FunctionalException; -import fr.inrae.agroclim.indicators.exception.TechnicalException; +import fr.inrae.agroclim.indicators.exception.IndicatorsException; +import fr.inrae.agroclim.indicators.exception.type.ComputationErrorType; import fr.inrae.agroclim.indicators.model.data.DailyData; import fr.inrae.agroclim.indicators.model.data.Resource; import lombok.EqualsAndHashCode; @@ -67,13 +67,12 @@ public final class MaxWaveLength extends SimpleIndicatorWithCriteria implements } @Override - public double computeSingleValue(final Resource<? extends DailyData> climatic) - throws TechnicalException, FunctionalException { + public double computeSingleValue(final Resource<? extends DailyData> climatic) throws IndicatorsException { if (getCriteria() == null) { - throw new RuntimeException("criteria must not be null!"); + throw new IndicatorsException(ComputationErrorType.CRITERIA_NULL); } if (threshold == null) { - throw new RuntimeException("threshold must not be null!"); + throw new IndicatorsException(ComputationErrorType.THRESHOLD_NULL); } int waveLength = 0; int max = 0; diff --git a/src/main/java/fr/inrae/agroclim/indicators/model/indicator/NumberOfDays.java b/src/main/java/fr/inrae/agroclim/indicators/model/indicator/NumberOfDays.java index 048102c8..9ffa5fbf 100644 --- a/src/main/java/fr/inrae/agroclim/indicators/model/indicator/NumberOfDays.java +++ b/src/main/java/fr/inrae/agroclim/indicators/model/indicator/NumberOfDays.java @@ -20,8 +20,7 @@ import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlRootElement; -import fr.inrae.agroclim.indicators.exception.FunctionalException; -import fr.inrae.agroclim.indicators.exception.TechnicalException; +import fr.inrae.agroclim.indicators.exception.IndicatorsException; import fr.inrae.agroclim.indicators.model.data.DailyData; import fr.inrae.agroclim.indicators.model.data.Resource; @@ -57,8 +56,7 @@ public final class NumberOfDays extends SimpleIndicatorWithCriteria implements D } @Override - public double computeSingleValue(final Resource<? extends DailyData> res) - throws TechnicalException, FunctionalException { + public double computeSingleValue(final Resource<? extends DailyData> res) throws IndicatorsException { if (getCriteria() == null) { return res.getData().size(); } diff --git a/src/main/java/fr/inrae/agroclim/indicators/model/indicator/NumberOfWaves.java b/src/main/java/fr/inrae/agroclim/indicators/model/indicator/NumberOfWaves.java index 06b8074f..24ce21fa 100644 --- a/src/main/java/fr/inrae/agroclim/indicators/model/indicator/NumberOfWaves.java +++ b/src/main/java/fr/inrae/agroclim/indicators/model/indicator/NumberOfWaves.java @@ -20,8 +20,8 @@ import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlElement; -import fr.inrae.agroclim.indicators.exception.FunctionalException; -import fr.inrae.agroclim.indicators.exception.TechnicalException; +import fr.inrae.agroclim.indicators.exception.IndicatorsException; +import fr.inrae.agroclim.indicators.exception.type.ComputationErrorType; import fr.inrae.agroclim.indicators.model.Parameter; import fr.inrae.agroclim.indicators.model.data.DailyData; import fr.inrae.agroclim.indicators.model.data.Resource; @@ -77,13 +77,12 @@ public final class NumberOfWaves extends SimpleIndicatorWithCriteria implements } @Override - public double computeSingleValue(final Resource<? extends DailyData> climatic) - throws TechnicalException, FunctionalException { + public double computeSingleValue(final Resource<? extends DailyData> climatic) throws IndicatorsException { if (getCriteria() == null) { - throw new RuntimeException("criteria must not be null!"); + throw new IndicatorsException(ComputationErrorType.CRITERIA_NULL); } if (nbDays == null) { - throw new RuntimeException("nbDays must not be null!"); + throw new IndicatorsException(ComputationErrorType.WRONG_DEFINITION, "nbDays must not be null!"); } int index = 0; int nb = 0; diff --git a/src/main/java/fr/inrae/agroclim/indicators/model/indicator/PhaseLength.java b/src/main/java/fr/inrae/agroclim/indicators/model/indicator/PhaseLength.java index 0347a871..12ace4a4 100644 --- a/src/main/java/fr/inrae/agroclim/indicators/model/indicator/PhaseLength.java +++ b/src/main/java/fr/inrae/agroclim/indicators/model/indicator/PhaseLength.java @@ -19,8 +19,7 @@ package fr.inrae.agroclim.indicators.model.indicator; import java.util.HashSet; import java.util.Set; -import fr.inrae.agroclim.indicators.exception.FunctionalException; -import fr.inrae.agroclim.indicators.exception.TechnicalException; +import fr.inrae.agroclim.indicators.exception.IndicatorsException; import fr.inrae.agroclim.indicators.model.data.DailyData; import fr.inrae.agroclim.indicators.model.data.Resource; import fr.inrae.agroclim.indicators.model.data.Variable; @@ -50,8 +49,7 @@ implements Detailable { } @Override - public double computeSingleValue(final Resource<? extends DailyData> data) - throws TechnicalException, FunctionalException { + public double computeSingleValue(final Resource<? extends DailyData> data) throws IndicatorsException { return data.getData().size(); } diff --git a/src/main/java/fr/inrae/agroclim/indicators/model/indicator/PotentialSowingDaysFrequency.java b/src/main/java/fr/inrae/agroclim/indicators/model/indicator/PotentialSowingDaysFrequency.java index ffc4ccc8..54dc714d 100644 --- a/src/main/java/fr/inrae/agroclim/indicators/model/indicator/PotentialSowingDaysFrequency.java +++ b/src/main/java/fr/inrae/agroclim/indicators/model/indicator/PotentialSowingDaysFrequency.java @@ -24,8 +24,7 @@ import java.util.Set; import javax.xml.bind.annotation.XmlType; -import fr.inrae.agroclim.indicators.exception.FunctionalException; -import fr.inrae.agroclim.indicators.exception.TechnicalException; +import fr.inrae.agroclim.indicators.exception.IndicatorsException; import fr.inrae.agroclim.indicators.model.Knowledge; import fr.inrae.agroclim.indicators.model.Parameter; import fr.inrae.agroclim.indicators.model.data.DailyData; @@ -35,6 +34,7 @@ import fr.inrae.agroclim.indicators.model.data.climate.ClimaticDailyData; import fr.inrae.agroclim.indicators.model.data.climate.ClimaticResource; import fr.inrae.agroclim.indicators.util.Doublet; import java.util.ArrayList; +import java.util.Objects; import java.util.Optional; import lombok.Getter; import lombok.Setter; @@ -158,12 +158,8 @@ public final class PotentialSowingDaysFrequency extends SimpleIndicator implemen } @Override - public double computeSingleValue( - final Resource<? extends DailyData> resource) - throws TechnicalException, FunctionalException { - if (resource == null) { - throw new IllegalArgumentException("resource must not be null!"); - } + public double computeSingleValue(final Resource<? extends DailyData> resource) throws IndicatorsException { + Objects.requireNonNull(resource, "Resource must not be null!"); if (!(resource instanceof ClimaticResource)) { throw new IllegalArgumentException( getClass().getName() diff --git a/src/main/java/fr/inrae/agroclim/indicators/model/indicator/Quotient.java b/src/main/java/fr/inrae/agroclim/indicators/model/indicator/Quotient.java index b3d9e520..87ec9eef 100644 --- a/src/main/java/fr/inrae/agroclim/indicators/model/indicator/Quotient.java +++ b/src/main/java/fr/inrae/agroclim/indicators/model/indicator/Quotient.java @@ -28,8 +28,8 @@ import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlType; -import fr.inrae.agroclim.indicators.exception.FunctionalException; -import fr.inrae.agroclim.indicators.exception.TechnicalException; +import fr.inrae.agroclim.indicators.exception.IndicatorsException; +import fr.inrae.agroclim.indicators.exception.type.ComputationErrorType; import fr.inrae.agroclim.indicators.model.Knowledge; import fr.inrae.agroclim.indicators.model.Parameter; import fr.inrae.agroclim.indicators.model.data.DailyData; @@ -93,35 +93,27 @@ public final class Quotient extends SimpleIndicator implements Detailable, Indic } @Override - public double computeSingleValue(final Resource<? extends DailyData> data) - throws TechnicalException, FunctionalException { + public double computeSingleValue(final Resource<? extends DailyData> data) throws IndicatorsException { if (dividend == null) { - throw new TechnicalException( - "Dividend indicator should never be null! Check " - + "this indicator " + getId()); + throw new IndicatorsException(ComputationErrorType.QUOTIENT_DIVIDEND_NULL); } if (divisor == null) { - throw new TechnicalException( - "Divisor indicator should never be null! Check " - + "this indicator " + getId()); + throw new IndicatorsException(ComputationErrorType.QUOTIENT_DIVISOR_NULL); } final double dividendValue; try { dividendValue = dividend.compute(data); - } catch (final NullPointerException e) { - throw new FunctionalException("Computed value of divident " - + dividend.getId() + " is null", e); + } catch (final IndicatorsException e) { + throw new IndicatorsException(ComputationErrorType.QUOTIENT_DIVIDEND_EXCEPTION, e, dividend.getId()); } final double divisorValue; try { divisorValue = divisor.compute(data); - } catch (final NullPointerException e) { - throw new FunctionalException("Computed value of divisor " - + divisor.getId() + " is null", e); + } catch (final IndicatorsException e) { + throw new IndicatorsException(ComputationErrorType.QUOTIENT_DIVISOR_EXCEPTION, e, divisor.getId()); } if (divisorValue == 0.0) { - throw new FunctionalException("Cannot compute value for '" + getId() + "' as value of divisor '" - + divisor.getId() + "' is 0."); + throw new IndicatorsException(ComputationErrorType.QUOTIENT_DIVISOR_ZERO, divisor.getId()); } return dividendValue / divisorValue; } diff --git a/src/main/java/fr/inrae/agroclim/indicators/model/indicator/SimpleIndicator.java b/src/main/java/fr/inrae/agroclim/indicators/model/indicator/SimpleIndicator.java index 5afa03a7..f09ec130 100644 --- a/src/main/java/fr/inrae/agroclim/indicators/model/indicator/SimpleIndicator.java +++ b/src/main/java/fr/inrae/agroclim/indicators/model/indicator/SimpleIndicator.java @@ -18,8 +18,7 @@ package fr.inrae.agroclim.indicators.model.indicator; import javax.xml.bind.annotation.XmlSeeAlso; -import fr.inrae.agroclim.indicators.exception.FunctionalException; -import fr.inrae.agroclim.indicators.exception.TechnicalException; +import fr.inrae.agroclim.indicators.exception.IndicatorsException; import fr.inrae.agroclim.indicators.model.EvaluationType; import fr.inrae.agroclim.indicators.model.data.DailyData; import fr.inrae.agroclim.indicators.model.data.Resource; @@ -73,19 +72,10 @@ public abstract class SimpleIndicator extends Indicator { * @param data * climatic resource used to compute indicator. * @return normalized result - * @throws fr.inrae.agroclim.indicators.exception.TechnicalException - * @throws fr.inrae.agroclim.indicators.exception.FunctionalException */ @Override - public final Double compute(final Resource<? extends DailyData> data) - throws TechnicalException, FunctionalException { - double value; - try { - value = computeSingleValue(data); - } catch (TechnicalException | FunctionalException e) { - LOGGER.warn("Indicator '{}' failed to compute single value: {}.", getId(), e.getMessage()); - throw e; - } + public final Double compute(final Resource<? extends DailyData> data) throws IndicatorsException { + double value = computeSingleValue(data); setNotNormalizedValue(value); if (getNormalizationFunction() != null && getType() != EvaluationType.WITHOUT_AGGREGATION) { @@ -101,13 +91,10 @@ public abstract class SimpleIndicator extends Indicator { * @param data * resource with daily data * @return value - * @throws TechnicalException - * exception - * @throws FunctionalException + * @throws IndicatorsException * exception */ - public abstract double computeSingleValue(Resource<? extends DailyData> data) - throws TechnicalException, FunctionalException; + public abstract double computeSingleValue(Resource<? extends DailyData> data) throws IndicatorsException; @Override public final void fireValueUpdated() { diff --git a/src/main/java/fr/inrae/agroclim/indicators/model/indicator/Tamm.java b/src/main/java/fr/inrae/agroclim/indicators/model/indicator/Tamm.java index d0904fbb..a7bf8a88 100644 --- a/src/main/java/fr/inrae/agroclim/indicators/model/indicator/Tamm.java +++ b/src/main/java/fr/inrae/agroclim/indicators/model/indicator/Tamm.java @@ -25,8 +25,7 @@ import java.util.Set; import javax.xml.bind.annotation.XmlType; -import fr.inrae.agroclim.indicators.exception.FunctionalException; -import fr.inrae.agroclim.indicators.exception.TechnicalException; +import fr.inrae.agroclim.indicators.exception.IndicatorsException; import fr.inrae.agroclim.indicators.model.Knowledge; import fr.inrae.agroclim.indicators.model.Parameter; import fr.inrae.agroclim.indicators.model.data.DailyData; @@ -154,8 +153,7 @@ public final class Tamm extends SimpleIndicator implements Detailable { } @Override - public double computeSingleValue(final Resource<? extends DailyData> data) - throws TechnicalException, FunctionalException { + public double computeSingleValue(final Resource<? extends DailyData> data) throws IndicatorsException { return data.getData().stream() // .map(this::computeDailyValue) // .reduce((v1, v2) -> v1 + v2).orElseThrow(); diff --git a/src/test/java/fr/inrae/agroclim/indicators/model/CulturalPracticesTest.java b/src/test/java/fr/inrae/agroclim/indicators/model/CulturalPracticesTest.java index b869201a..55d2cedd 100644 --- a/src/test/java/fr/inrae/agroclim/indicators/model/CulturalPracticesTest.java +++ b/src/test/java/fr/inrae/agroclim/indicators/model/CulturalPracticesTest.java @@ -19,8 +19,7 @@ package fr.inrae.agroclim.indicators.model; -import fr.inrae.agroclim.indicators.exception.FunctionalException; -import fr.inrae.agroclim.indicators.exception.TechnicalException; +import fr.inrae.agroclim.indicators.exception.IndicatorsException; import fr.inrae.agroclim.indicators.model.data.DataTestHelper; import java.io.File; import lombok.extern.log4j.Log4j2; @@ -76,7 +75,7 @@ public class CulturalPracticesTest extends DataTestHelper { long start = System.currentTimeMillis(); evaluation.compute(); LOGGER.info("Evaluation.compute() last {} seconds", (System.currentTimeMillis() - start) / 1000.); - } catch (final TechnicalException | FunctionalException e) { + } catch (final IndicatorsException e) { LOGGER.catching(e); error = e.getClass() + " : " + e.getLocalizedMessage(); } diff --git a/src/test/java/fr/inrae/agroclim/indicators/model/EvaluationHourlyTest.java b/src/test/java/fr/inrae/agroclim/indicators/model/EvaluationHourlyTest.java index 10eb9d61..f90f64f0 100644 --- a/src/test/java/fr/inrae/agroclim/indicators/model/EvaluationHourlyTest.java +++ b/src/test/java/fr/inrae/agroclim/indicators/model/EvaluationHourlyTest.java @@ -12,8 +12,7 @@ import java.util.Map; import org.junit.Before; import org.junit.Test; -import fr.inrae.agroclim.indicators.exception.FunctionalException; -import fr.inrae.agroclim.indicators.exception.TechnicalException; +import fr.inrae.agroclim.indicators.exception.IndicatorsException; import fr.inrae.agroclim.indicators.model.data.DataTestHelper; import fr.inrae.agroclim.indicators.model.result.EvaluationResult; import fr.inrae.agroclim.indicators.model.result.IndicatorResult; @@ -57,7 +56,7 @@ public class EvaluationHourlyTest extends DataTestHelper { try { evaluation.initializeResources(); evaluation.compute(); - } catch (final TechnicalException | FunctionalException e) { + } catch (final IndicatorsException e) { error = e.getClass() + " : " + e.getLocalizedMessage(); } assertNull(error, error); diff --git a/src/test/java/fr/inrae/agroclim/indicators/model/EvaluationRobertTest.java b/src/test/java/fr/inrae/agroclim/indicators/model/EvaluationRobertTest.java index 16aae0ed..e1a505c3 100644 --- a/src/test/java/fr/inrae/agroclim/indicators/model/EvaluationRobertTest.java +++ b/src/test/java/fr/inrae/agroclim/indicators/model/EvaluationRobertTest.java @@ -18,8 +18,7 @@ */ package fr.inrae.agroclim.indicators.model; -import fr.inrae.agroclim.indicators.exception.FunctionalException; -import fr.inrae.agroclim.indicators.exception.TechnicalException; +import fr.inrae.agroclim.indicators.exception.IndicatorsException; import fr.inrae.agroclim.indicators.model.data.DataTestHelper; import fr.inrae.agroclim.indicators.model.data.climate.ClimaticResource; import fr.inrae.agroclim.indicators.model.result.EvaluationResult; @@ -82,7 +81,7 @@ public class EvaluationRobertTest extends DataTestHelper { try { evaluation.initializeResources(); evaluation.compute(); - } catch (final TechnicalException | FunctionalException e) { + } catch (final IndicatorsException e) { error = e.getClass() + " : " + e.getLocalizedMessage(); } assertNull(error, error); diff --git a/src/test/java/fr/inrae/agroclim/indicators/model/EvaluationTest.java b/src/test/java/fr/inrae/agroclim/indicators/model/EvaluationTest.java index a1d8b3e9..a7bf99dd 100644 --- a/src/test/java/fr/inrae/agroclim/indicators/model/EvaluationTest.java +++ b/src/test/java/fr/inrae/agroclim/indicators/model/EvaluationTest.java @@ -40,8 +40,7 @@ import java.util.stream.Collectors; import org.junit.Before; import org.junit.Test; -import fr.inrae.agroclim.indicators.exception.FunctionalException; -import fr.inrae.agroclim.indicators.exception.TechnicalException; +import fr.inrae.agroclim.indicators.exception.IndicatorsException; import fr.inrae.agroclim.indicators.model.data.DataTestHelper; import fr.inrae.agroclim.indicators.model.data.ResourceManager; import fr.inrae.agroclim.indicators.model.data.Variable; @@ -68,7 +67,7 @@ public final class EvaluationTest extends DataTestHelper { * Evaluation from good XML file. */ private Evaluation evaluation; - + /** * Evaluation from good XML file and with a climatic file contains NA data. */ @@ -123,12 +122,12 @@ public final class EvaluationTest extends DataTestHelper { try { evaluation.initializeResources(); evaluation.compute(); - } catch (final TechnicalException | FunctionalException e) { + } catch (final IndicatorsException e) { error = e.getClass() + " : " + e.getLocalizedMessage(); } assertNull(error, error); } - + @Test public void computableWithNoData() { final File xmlFile = getEvaluationWithNoDataTestFile(); @@ -139,11 +138,11 @@ public final class EvaluationTest extends DataTestHelper { evaluationWithNoData.initializeResources(); try { evaluationWithNoData.compute(); - } catch (final TechnicalException | FunctionalException e) { + } catch (final IndicatorsException e) { error = e.getClass() + " : " + e.getLocalizedMessage(); } assertNull(error, error); - + } /** @@ -190,7 +189,7 @@ public final class EvaluationTest extends DataTestHelper { final int nbOfPhases = evaluation.getIndicators().size(); final int nbOfYears = evaluation.getClimaticResource().getYears().size(); assertEquals(nbOfPhases * nbOfYears, phases.size()); - } catch (final TechnicalException | FunctionalException e) { + } catch (final IndicatorsException e) { error = e.getClass() + " : " + e.getLocalizedMessage(); } assertNull(error, error); @@ -260,7 +259,7 @@ public final class EvaluationTest extends DataTestHelper { }); }); }); - } catch (final TechnicalException | FunctionalException e) { + } catch (final IndicatorsException e) { throw new RuntimeException("This should never occur.", e); } assertTrue(duplicates.toString(), duplicates.isEmpty()); @@ -424,7 +423,7 @@ public final class EvaluationTest extends DataTestHelper { try { evaluation.initializeResources(); evaluation.compute(); - } catch (final TechnicalException | FunctionalException e) { + } catch (final IndicatorsException e) { error = e.getClass() + " : " + e.getLocalizedMessage(); } assertNull(error, error); @@ -440,7 +439,7 @@ public final class EvaluationTest extends DataTestHelper { evaluation.setParametersValues(parameters); try { evaluation.compute(); - } catch (TechnicalException | FunctionalException e) { + } catch (IndicatorsException e) { error = e.getClass() + " : " + e.getLocalizedMessage(); } assertNull(error, error); diff --git a/src/test/java/fr/inrae/agroclim/indicators/model/EvaluationWithoutAggregationTest.java b/src/test/java/fr/inrae/agroclim/indicators/model/EvaluationWithoutAggregationTest.java index 989ea677..e9a8794d 100644 --- a/src/test/java/fr/inrae/agroclim/indicators/model/EvaluationWithoutAggregationTest.java +++ b/src/test/java/fr/inrae/agroclim/indicators/model/EvaluationWithoutAggregationTest.java @@ -18,7 +18,7 @@ */ package fr.inrae.agroclim.indicators.model; -import fr.inrae.agroclim.indicators.exception.FunctionalException; +import fr.inrae.agroclim.indicators.exception.IndicatorsException; import fr.inrae.agroclim.indicators.exception.TechnicalException; import fr.inrae.agroclim.indicators.model.data.DataTestHelper; import fr.inrae.agroclim.indicators.model.indicator.CompositeIndicator; @@ -76,13 +76,10 @@ public class EvaluationWithoutAggregationTest extends DataTestHelper { /** * Check if evaluation computes. - * @throws fr.inrae.agroclim.indicators.exception.TechnicalException while - * computing - * @throws fr.inrae.agroclim.indicators.exception.FunctionalException while - * computing + * @throws IndicatorsException while computing */ @Test(expected = Test.None.class) - public void compute() throws TechnicalException, FunctionalException { + public void compute() throws IndicatorsException { assertNotNull("Evaluation must not be null!", evaluation); evaluation.initializeResources(); evaluation.compute(); diff --git a/src/test/java/fr/inrae/agroclim/indicators/model/EvalutationCustomHeadersTest.java b/src/test/java/fr/inrae/agroclim/indicators/model/EvalutationCustomHeadersTest.java index f7bd5554..325eaa03 100644 --- a/src/test/java/fr/inrae/agroclim/indicators/model/EvalutationCustomHeadersTest.java +++ b/src/test/java/fr/inrae/agroclim/indicators/model/EvalutationCustomHeadersTest.java @@ -18,8 +18,7 @@ */ package fr.inrae.agroclim.indicators.model; -import fr.inrae.agroclim.indicators.exception.FunctionalException; -import fr.inrae.agroclim.indicators.exception.TechnicalException; +import fr.inrae.agroclim.indicators.exception.IndicatorsException; import fr.inrae.agroclim.indicators.model.data.DataTestHelper; import fr.inrae.agroclim.indicators.model.result.EvaluationResult; import java.io.File; @@ -65,7 +64,7 @@ public class EvalutationCustomHeadersTest extends DataTestHelper { try { evaluation.initializeResources(); evaluation.compute(); - } catch (final TechnicalException | FunctionalException e) { + } catch (final IndicatorsException e) { error = e.getClass() + " : " + e.getLocalizedMessage(); } assertNull(error, error); diff --git a/src/test/java/fr/inrae/agroclim/indicators/model/JEXLFormulaTest.java b/src/test/java/fr/inrae/agroclim/indicators/model/JEXLFormulaTest.java index b80a7ffc..908876e5 100644 --- a/src/test/java/fr/inrae/agroclim/indicators/model/JEXLFormulaTest.java +++ b/src/test/java/fr/inrae/agroclim/indicators/model/JEXLFormulaTest.java @@ -18,7 +18,7 @@ */ package fr.inrae.agroclim.indicators.model; -import fr.inrae.agroclim.indicators.exception.FunctionalException; +import fr.inrae.agroclim.indicators.exception.IndicatorsException; import fr.inrae.agroclim.indicators.model.data.Variable; import java.util.HashMap; import java.util.HashSet; @@ -55,7 +55,7 @@ public class JEXLFormulaTest { } @Test - public void useFormulaCriteria() throws FunctionalException { + public void useFormulaCriteria() throws IndicatorsException { final JEXLFormula formula = new JEXLFormula(); formula.setExpression("formulaCriteria:between(2, 1, 3)"); var actual = formula.evaluate(new HashMap<>(), Boolean.class); @@ -63,7 +63,7 @@ public class JEXLFormulaTest { } @Test - public void useMathMethod() throws FunctionalException { + public void useMathMethod() throws IndicatorsException { final JEXLFormula formula = new JEXLFormula(); formula.setExpression("math:min(2, 1, 3)"); var actual = formula.evaluate(new HashMap<>(), Double.class); diff --git a/src/test/java/fr/inrae/agroclim/indicators/model/KnowledgeTest.java b/src/test/java/fr/inrae/agroclim/indicators/model/KnowledgeTest.java index 92ca75b2..3b44ce15 100644 --- a/src/test/java/fr/inrae/agroclim/indicators/model/KnowledgeTest.java +++ b/src/test/java/fr/inrae/agroclim/indicators/model/KnowledgeTest.java @@ -347,6 +347,7 @@ public final class KnowledgeTest { @Test public void noNullVariables() { getSimpleIndicators().forEach((ind) -> { + System.out.println("=> " + ind); assertNotNull(ind); final String id = ind.getId(); final Set<Variable> vars = ind.getVariables(); diff --git a/src/test/java/fr/inrae/agroclim/indicators/model/MMarjouTest.java b/src/test/java/fr/inrae/agroclim/indicators/model/MMarjouTest.java index 34ef61c4..75ca9303 100644 --- a/src/test/java/fr/inrae/agroclim/indicators/model/MMarjouTest.java +++ b/src/test/java/fr/inrae/agroclim/indicators/model/MMarjouTest.java @@ -16,8 +16,7 @@ */ package fr.inrae.agroclim.indicators.model; -import fr.inrae.agroclim.indicators.exception.FunctionalException; -import fr.inrae.agroclim.indicators.exception.TechnicalException; +import fr.inrae.agroclim.indicators.exception.IndicatorsException; import fr.inrae.agroclim.indicators.model.data.DataTestHelper; import fr.inrae.agroclim.indicators.model.data.phenology.AnnualStageData; import fr.inrae.agroclim.indicators.model.result.EvaluationResult; @@ -80,7 +79,7 @@ public class MMarjouTest extends DataTestHelper { long start = System.currentTimeMillis(); evaluation.compute(); LOGGER.info("Evaluation.compute() last {} seconds", (System.currentTimeMillis() - start) / 1000.); - } catch (final TechnicalException | FunctionalException e) { + } catch (final IndicatorsException e) { error = e.getClass() + " : " + e.getLocalizedMessage(); } assertNull(error, error); diff --git a/src/test/java/fr/inrae/agroclim/indicators/model/RaidayMeantTest.java b/src/test/java/fr/inrae/agroclim/indicators/model/RaidayMeantTest.java index 1579b2f2..ffacfcdc 100644 --- a/src/test/java/fr/inrae/agroclim/indicators/model/RaidayMeantTest.java +++ b/src/test/java/fr/inrae/agroclim/indicators/model/RaidayMeantTest.java @@ -23,7 +23,6 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import java.io.File; -import java.io.IOException; import java.nio.file.Paths; import java.text.SimpleDateFormat; import java.util.Arrays; @@ -37,7 +36,7 @@ import java.util.stream.IntStream; import org.junit.Before; import org.junit.Test; -import fr.inrae.agroclim.indicators.exception.FunctionalException; +import fr.inrae.agroclim.indicators.exception.IndicatorsException; import fr.inrae.agroclim.indicators.exception.TechnicalException; import fr.inrae.agroclim.indicators.model.criteria.RelationalOperator; import fr.inrae.agroclim.indicators.model.criteria.SimpleCriteria; @@ -57,6 +56,7 @@ import fr.inrae.agroclim.indicators.model.result.IndicatorResult; import fr.inrae.agroclim.indicators.model.result.PhaseResult; import fr.inrae.agroclim.indicators.util.DateUtils; import fr.inrae.agroclim.indicators.xml.XMLUtil; +import java.io.IOException; import java.util.TimeZone; import lombok.NonNull; import lombok.extern.log4j.Log4j2; @@ -224,7 +224,7 @@ public class RaidayMeantTest extends DataTestHelper { evaluation.initializeResources(); evaluation.compute(); annualStageDatas = evaluation.getResourceManager().getPhenologicalResource().getData(); - } catch (final TechnicalException | FunctionalException | IOException e) { + } catch (final IndicatorsException | IOException e) { error = e.getClass() + " : " + e.getLocalizedMessage(); } assertNull(error, error); @@ -253,7 +253,7 @@ public class RaidayMeantTest extends DataTestHelper { try { evaluation.initializeResources(); evaluation.compute(); - } catch (final TechnicalException | FunctionalException e) { + } catch (final IndicatorsException e) { error = e.getClass() + " : " + e.getLocalizedMessage(); } assertNull(error, error); diff --git a/src/test/java/fr/inrae/agroclim/indicators/model/StageDeltaEvaluationTest.java b/src/test/java/fr/inrae/agroclim/indicators/model/StageDeltaEvaluationTest.java index e3743d58..38b9d376 100644 --- a/src/test/java/fr/inrae/agroclim/indicators/model/StageDeltaEvaluationTest.java +++ b/src/test/java/fr/inrae/agroclim/indicators/model/StageDeltaEvaluationTest.java @@ -27,7 +27,7 @@ import java.util.Map; import org.junit.Before; import org.junit.Test; -import fr.inrae.agroclim.indicators.exception.FunctionalException; +import fr.inrae.agroclim.indicators.exception.IndicatorsException; import fr.inrae.agroclim.indicators.exception.TechnicalException; import fr.inrae.agroclim.indicators.model.data.DataTestHelper; import fr.inrae.agroclim.indicators.xml.XMLUtil; @@ -92,7 +92,7 @@ public class StageDeltaEvaluationTest extends DataTestHelper { final long start = System.currentTimeMillis(); evaluation.compute(); LOGGER.info("Evaluation.compute() last {} seconds", (System.currentTimeMillis() - start) / 1000.); - } catch (final TechnicalException | FunctionalException e) { + } catch (final IndicatorsException e) { error = e.getClass() + " : " + e.getLocalizedMessage(); } assertNull(error, error); diff --git a/src/test/java/fr/inrae/agroclim/indicators/model/criteria/CompositeCriteriaTest.java b/src/test/java/fr/inrae/agroclim/indicators/model/criteria/CompositeCriteriaTest.java index 3b198104..d37518aa 100644 --- a/src/test/java/fr/inrae/agroclim/indicators/model/criteria/CompositeCriteriaTest.java +++ b/src/test/java/fr/inrae/agroclim/indicators/model/criteria/CompositeCriteriaTest.java @@ -16,6 +16,7 @@ */ package fr.inrae.agroclim.indicators.model.criteria; +import fr.inrae.agroclim.indicators.exception.IndicatorsException; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; @@ -24,7 +25,6 @@ import java.util.List; import org.junit.Test; -import fr.inrae.agroclim.indicators.exception.TechnicalException; import fr.inrae.agroclim.indicators.model.data.climate.ClimaticDailyData; /** @@ -88,11 +88,11 @@ public final class CompositeCriteriaTest { /** * Check sup0 AND inf10 criteria. * - * @throws TechnicalException + * @throws IndicatorsException * exception while getting value. */ @Test - public void and() throws TechnicalException { + public void and() throws IndicatorsException { criteria.setLogicalOperator(LogicalOperator.AND); assertFalse(criteria.getFormula(data0) + " must be false", criteria.eval(data0)); @@ -105,11 +105,11 @@ public final class CompositeCriteriaTest { /** * Check inf10 criteria. * - * @throws TechnicalException + * @throws IndicatorsException * exception while getting value. */ @Test - public void inf10() throws TechnicalException { + public void inf10() throws IndicatorsException { assertTrue(inf10.getFormula(data0) + " must be true", inf10.eval(data0)); assertTrue(inf10.getFormula(data5) + " must be true", @@ -121,11 +121,11 @@ public final class CompositeCriteriaTest { /** * Check sup0 OR inf10 criteria. * - * @throws TechnicalException + * @throws IndicatorsException * exception while getting value. */ @Test - public void or() throws TechnicalException { + public void or() throws IndicatorsException { criteria.setLogicalOperator(LogicalOperator.OR); assertTrue(criteria.getFormula(data0) + " must be true", criteria.eval(data0)); @@ -138,11 +138,11 @@ public final class CompositeCriteriaTest { /** * Check sup0 criteria. * - * @throws TechnicalException + * @throws IndicatorsException * exception while getting value. */ @Test - public void sup0() throws TechnicalException { + public void sup0() throws IndicatorsException { assertFalse( sup0.getFormula(data0) + " must be false. " + sup0.toString(), sup0.eval(data0)); @@ -154,11 +154,11 @@ public final class CompositeCriteriaTest { /** * Check sup0 XOR inf10 criteria. * - * @throws TechnicalException + * @throws IndicatorsException * exception while getting value. */ @Test - public void xor() throws TechnicalException { + public void xor() throws IndicatorsException { criteria.setLogicalOperator(LogicalOperator.XOR); assertTrue(criteria.getFormula(data0) + " must be true", criteria.eval(data0)); diff --git a/src/test/java/fr/inrae/agroclim/indicators/model/criteria/FormulaCriteriaTest.java b/src/test/java/fr/inrae/agroclim/indicators/model/criteria/FormulaCriteriaTest.java index 53fa19e2..63820714 100644 --- a/src/test/java/fr/inrae/agroclim/indicators/model/criteria/FormulaCriteriaTest.java +++ b/src/test/java/fr/inrae/agroclim/indicators/model/criteria/FormulaCriteriaTest.java @@ -18,6 +18,7 @@ */ package fr.inrae.agroclim.indicators.model.criteria; +import fr.inrae.agroclim.indicators.exception.IndicatorsException; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; @@ -73,14 +74,14 @@ public class FormulaCriteriaTest { } @Test - public void formulaFunction() throws TechnicalException { + public void formulaFunction() throws IndicatorsException { final FormulaCriteria crit = new FormulaCriteria(); crit.setExpression("formulaCriteria:between(TMEAN, 10, 20)"); assertTrue(crit.eval(data)); } @Test - public void formulaWithParameter() throws TechnicalException { + public void formulaWithParameter() throws IndicatorsException, TechnicalException { final FormulaCriteria crit = new FormulaCriteria(); crit.setExpression("formulaCriteria:between(TMEAN, min, max)"); final List<ExpressionParameter> expressionParameters = new ArrayList<>(); @@ -120,8 +121,8 @@ public class FormulaCriteriaTest { assertTrue(variables.contains(Variable.TMEAN)); } - @Test(expected = TechnicalException.class) - public void wrongFunction() throws TechnicalException { + @Test(expected = IndicatorsException.class) + public void wrongFunction() throws IndicatorsException { final FormulaCriteria crit = new FormulaCriteria(); crit.setExpression("that:notExists(TMEAN, 10, 20)"); crit.eval(data); diff --git a/src/test/java/fr/inrae/agroclim/indicators/model/criteria/SimpleCriteriaTest.java b/src/test/java/fr/inrae/agroclim/indicators/model/criteria/SimpleCriteriaTest.java index ca9a0d88..a74af17e 100644 --- a/src/test/java/fr/inrae/agroclim/indicators/model/criteria/SimpleCriteriaTest.java +++ b/src/test/java/fr/inrae/agroclim/indicators/model/criteria/SimpleCriteriaTest.java @@ -1,5 +1,6 @@ package fr.inrae.agroclim.indicators.model.criteria; +import fr.inrae.agroclim.indicators.exception.IndicatorsException; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; @@ -48,7 +49,7 @@ public class SimpleCriteriaTest { } @Test - public void gt() throws TechnicalException { + public void gt() throws IndicatorsException { final double dek = 10.; final SimpleCriteria criteria = new SimpleCriteria(); criteria.setOperator(RelationalOperator.GT); @@ -59,7 +60,7 @@ public class SimpleCriteriaTest { } @Test - public void le() throws TechnicalException { + public void le() throws IndicatorsException { final double dek = 10.; final SimpleCriteria criteria = new SimpleCriteria(); criteria.setOperator(RelationalOperator.LE); @@ -70,7 +71,7 @@ public class SimpleCriteriaTest { } @Test - public void inferiorToThreshold() throws TechnicalException { + public void inferiorToThreshold() throws IndicatorsException { final double dek = 10.; final SimpleCriteria criteria = new SimpleCriteria(); criteria.setInferiorToThreshold(true); @@ -111,7 +112,7 @@ public class SimpleCriteriaTest { } @Test(expected = Test.None.class) - public void unserializeGT() throws TechnicalException { + public void unserializeGT() throws IndicatorsException, TechnicalException { final Class<?>[] classes = new Class<?>[]{ Criteria.class, SimpleCriteria.class }; final String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>" + "<criteria xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:type=\"simpleCriteria\">" @@ -131,7 +132,7 @@ public class SimpleCriteriaTest { } @Test(expected = Test.None.class) - public void unserializeInferiorToThreshold() throws TechnicalException { + public void unserializeInferiorToThreshold() throws IndicatorsException, TechnicalException { final Class<?>[] classes = new Class<?>[]{ Criteria.class, SimpleCriteria.class }; final String xml = """ <?xml version="1.0" encoding="UTF-8" ?><criteria xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="simpleCriteria"> <variable>th</variable> diff --git a/src/test/java/fr/inrae/agroclim/indicators/model/function/aggregation/JEXLFunctionTest.java b/src/test/java/fr/inrae/agroclim/indicators/model/function/aggregation/JEXLFunctionTest.java index eedc6f65..5b226497 100644 --- a/src/test/java/fr/inrae/agroclim/indicators/model/function/aggregation/JEXLFunctionTest.java +++ b/src/test/java/fr/inrae/agroclim/indicators/model/function/aggregation/JEXLFunctionTest.java @@ -23,7 +23,7 @@ import java.util.HashMap; import org.junit.Test; -import fr.inrae.agroclim.indicators.exception.FunctionalException; +import fr.inrae.agroclim.indicators.exception.IndicatorsException; /** * Test JEXLFunction. @@ -52,12 +52,12 @@ public final class JEXLFunctionTest { final Double expected = a * MathMethod.min(b, 2.) - 10; final Double actual = func.aggregate(data); assertEquals(expected, actual); - } catch (final FunctionalException ex) { - error = ex.getMessage() + ex.getRootException(); + } catch (final IndicatorsException ex) { + error = ex.getMessage(); } assertNull(error); } - + /** * Test expression with variable names starting with $. */ @@ -75,8 +75,8 @@ public final class JEXLFunctionTest { final Double expected = one * MathMethod.min(two, 2.) - 10; final Double actual = func.aggregate(data); assertEquals(expected, actual); - } catch (final FunctionalException ex) { - error = ex.getMessage() + ex.getRootException(); + } catch (final IndicatorsException ex) { + error = ex.getMessage(); } assertNull(error); } @@ -99,8 +99,8 @@ public final class JEXLFunctionTest { final Double expected = one * MathMethod.min(two, 2) - 10; final Double actual = func.aggregate(data); assertEquals(expected, actual); - } catch (final FunctionalException ex) { - error = ex.getMessage() + ex.getRootException(); + } catch (final IndicatorsException ex) { + error = ex.getMessage(); } assertNull(error); } @@ -119,8 +119,8 @@ public final class JEXLFunctionTest { final Double expected = 0.; assertEquals(expected, actual); - } catch (final FunctionalException ex) { - error = ex.getMessage() + ex.getRootException(); + } catch (final IndicatorsException ex) { + error = ex.getMessage(); } assertNull(error); } diff --git a/src/test/java/fr/inrae/agroclim/indicators/model/indicator/AverageOfDiffTest.java b/src/test/java/fr/inrae/agroclim/indicators/model/indicator/AverageOfDiffTest.java index 790e6c59..7c73ef0c 100644 --- a/src/test/java/fr/inrae/agroclim/indicators/model/indicator/AverageOfDiffTest.java +++ b/src/test/java/fr/inrae/agroclim/indicators/model/indicator/AverageOfDiffTest.java @@ -18,8 +18,7 @@ */ package fr.inrae.agroclim.indicators.model.indicator; -import fr.inrae.agroclim.indicators.exception.FunctionalException; -import fr.inrae.agroclim.indicators.exception.TechnicalException; +import fr.inrae.agroclim.indicators.exception.IndicatorsException; import fr.inrae.agroclim.indicators.model.data.DataTestHelper; import fr.inrae.agroclim.indicators.model.data.Variable; import fr.inrae.agroclim.indicators.model.data.climate.ClimaticResource; @@ -69,7 +68,7 @@ public class AverageOfDiffTest extends DataTestHelper { String error = null; try { result = indicator.computeSingleValue(climaticData); - } catch (TechnicalException | FunctionalException ex) { + } catch (final IndicatorsException ex) { error = ex.getClass().getCanonicalName() + " : " + ex.getMessage(); } assertNull(error, error ); diff --git a/src/test/java/fr/inrae/agroclim/indicators/model/indicator/AverageTest.java b/src/test/java/fr/inrae/agroclim/indicators/model/indicator/AverageTest.java index 11db4ece..3014fe06 100644 --- a/src/test/java/fr/inrae/agroclim/indicators/model/indicator/AverageTest.java +++ b/src/test/java/fr/inrae/agroclim/indicators/model/indicator/AverageTest.java @@ -32,7 +32,7 @@ import java.nio.file.Path; import org.junit.Test; -import fr.inrae.agroclim.indicators.exception.FunctionalException; +import fr.inrae.agroclim.indicators.exception.IndicatorsException; import fr.inrae.agroclim.indicators.exception.TechnicalException; import fr.inrae.agroclim.indicators.model.Knowledge; import fr.inrae.agroclim.indicators.model.TimeScale; @@ -80,7 +80,7 @@ public class AverageTest extends DataTestHelper { String error = null; try { result = indicator.computeSingleValue(climaticData); - } catch (TechnicalException | FunctionalException ex) { + } catch (IndicatorsException ex) { error = ex.getClass().getCanonicalName() + " : " + ex.getMessage(); } assertEquals(null, error); @@ -94,7 +94,7 @@ public class AverageTest extends DataTestHelper { } @Test - public void mint() throws TechnicalException, FunctionalException, CloneNotSupportedException { + public void mint() throws TechnicalException, IndicatorsException, CloneNotSupportedException { final Knowledge knowledge = Knowledge.load(TimeScale.DAILY); final String indicatorId = "mint"; final IndicatorCategory expectedCat = IndicatorCategory.INDICATORS; diff --git a/src/test/java/fr/inrae/agroclim/indicators/model/indicator/ColdsumtminTest.java b/src/test/java/fr/inrae/agroclim/indicators/model/indicator/ColdsumtminTest.java index c8c02d5a..49bbe200 100644 --- a/src/test/java/fr/inrae/agroclim/indicators/model/indicator/ColdsumtminTest.java +++ b/src/test/java/fr/inrae/agroclim/indicators/model/indicator/ColdsumtminTest.java @@ -20,8 +20,7 @@ package fr.inrae.agroclim.indicators.model.indicator; import static junit.framework.TestCase.assertEquals; -import fr.inrae.agroclim.indicators.exception.FunctionalException; -import fr.inrae.agroclim.indicators.exception.TechnicalException; +import fr.inrae.agroclim.indicators.exception.IndicatorsException; import fr.inrae.agroclim.indicators.model.criteria.RelationalOperator; import fr.inrae.agroclim.indicators.model.criteria.SimpleCriteria; import org.junit.Test; @@ -53,7 +52,7 @@ public class ColdsumtminTest extends DataTestHelper { } @Test - public void test() throws TechnicalException, FunctionalException { + public void test() throws IndicatorsException { final Sum indicator = new Sum(); final SimpleCriteria criteria = new SimpleCriteria(); criteria.setVariable(Variable.TMIN); diff --git a/src/test/java/fr/inrae/agroclim/indicators/model/indicator/DayOfYearTest.java b/src/test/java/fr/inrae/agroclim/indicators/model/indicator/DayOfYearTest.java index 7d769ac8..a9ef8c8c 100644 --- a/src/test/java/fr/inrae/agroclim/indicators/model/indicator/DayOfYearTest.java +++ b/src/test/java/fr/inrae/agroclim/indicators/model/indicator/DayOfYearTest.java @@ -21,8 +21,7 @@ import static org.junit.Assert.assertNull; import org.junit.Test; -import fr.inrae.agroclim.indicators.exception.FunctionalException; -import fr.inrae.agroclim.indicators.exception.TechnicalException; +import fr.inrae.agroclim.indicators.exception.IndicatorsException; import fr.inrae.agroclim.indicators.model.criteria.Criteria; import fr.inrae.agroclim.indicators.model.criteria.RelationalOperator; import fr.inrae.agroclim.indicators.model.criteria.SimpleCriteria; @@ -76,7 +75,7 @@ public final class DayOfYearTest extends DataTestHelper { String error = null; try { result = indicator.computeSingleValue(climaticData); - } catch (TechnicalException | FunctionalException ex) { + } catch (final IndicatorsException ex) { error = ex.getClass().getCanonicalName() + " : " + ex.getMessage(); } assertNull(error, error); @@ -96,7 +95,7 @@ public final class DayOfYearTest extends DataTestHelper { String error = null; try { result = indicator.computeSingleValue(climaticData); - } catch (TechnicalException | FunctionalException ex) { + } catch (final IndicatorsException ex) { error = ex.getClass().getCanonicalName() + " : " + ex.getMessage(); } assertNull(error, error); diff --git a/src/test/java/fr/inrae/agroclim/indicators/model/indicator/DiffOfSumTest.java b/src/test/java/fr/inrae/agroclim/indicators/model/indicator/DiffOfSumTest.java index b371057d..92c0200a 100644 --- a/src/test/java/fr/inrae/agroclim/indicators/model/indicator/DiffOfSumTest.java +++ b/src/test/java/fr/inrae/agroclim/indicators/model/indicator/DiffOfSumTest.java @@ -5,7 +5,7 @@ import static org.junit.Assert.assertNull; import org.junit.Test; -import fr.inrae.agroclim.indicators.exception.FunctionalException; +import fr.inrae.agroclim.indicators.exception.IndicatorsException; import fr.inrae.agroclim.indicators.exception.TechnicalException; import fr.inrae.agroclim.indicators.model.Knowledge; import fr.inrae.agroclim.indicators.model.criteria.SimpleCriteria; @@ -62,7 +62,7 @@ public class DiffOfSumTest extends DataTestHelper { String error = null; try { result = indicator.computeSingleValue(climaticData); - } catch (TechnicalException | FunctionalException ex) { + } catch (final IndicatorsException ex) { error = ex.getClass().getCanonicalName() + " : " + ex.getMessage(); } assertNull(error, error); @@ -85,7 +85,7 @@ public class DiffOfSumTest extends DataTestHelper { String error = null; try { result = sumwd.computeSingleValue(climaticData); - } catch (TechnicalException | FunctionalException ex) { + } catch (final IndicatorsException ex) { error = ex.getClass().getCanonicalName() + " : " + ex.getMessage(); } assertNull(error, error); diff --git a/src/test/java/fr/inrae/agroclim/indicators/model/indicator/FormulaTest.java b/src/test/java/fr/inrae/agroclim/indicators/model/indicator/FormulaTest.java index 5b81634e..d132cdf4 100644 --- a/src/test/java/fr/inrae/agroclim/indicators/model/indicator/FormulaTest.java +++ b/src/test/java/fr/inrae/agroclim/indicators/model/indicator/FormulaTest.java @@ -36,8 +36,7 @@ import com.fasterxml.jackson.databind.MappingIterator; import com.fasterxml.jackson.dataformat.csv.CsvMapper; import com.fasterxml.jackson.dataformat.csv.CsvSchema; -import fr.inrae.agroclim.indicators.exception.FunctionalException; -import fr.inrae.agroclim.indicators.exception.TechnicalException; +import fr.inrae.agroclim.indicators.exception.IndicatorsException; import fr.inrae.agroclim.indicators.model.data.DataTestHelper; import fr.inrae.agroclim.indicators.model.data.climate.ClimaticDailyData; import fr.inrae.agroclim.indicators.model.data.climate.ClimaticResource; @@ -121,7 +120,7 @@ public class FormulaTest extends DataTestHelper { } @Test - public void computeSingleValue() throws TechnicalException, FunctionalException { + public void computeSingleValue() throws IndicatorsException { assertNotNull(this.data); assertNotNull(this.data.getRh()); assertNotNull(this.data.getTh()); @@ -132,7 +131,7 @@ public class FormulaTest extends DataTestHelper { } @Test - public void computeWithParameters() throws TechnicalException, FunctionalException { + public void computeWithParameters() throws IndicatorsException { assertNotNull(this.data); assertNotNull(this.data.getTh()); final double paramA = 10.; diff --git a/src/test/java/fr/inrae/agroclim/indicators/model/indicator/FrequencyTest.java b/src/test/java/fr/inrae/agroclim/indicators/model/indicator/FrequencyTest.java index 1b31ee44..2a0ea149 100644 --- a/src/test/java/fr/inrae/agroclim/indicators/model/indicator/FrequencyTest.java +++ b/src/test/java/fr/inrae/agroclim/indicators/model/indicator/FrequencyTest.java @@ -18,8 +18,7 @@ */ package fr.inrae.agroclim.indicators.model.indicator; -import fr.inrae.agroclim.indicators.exception.FunctionalException; -import fr.inrae.agroclim.indicators.exception.TechnicalException; +import fr.inrae.agroclim.indicators.exception.IndicatorsException; import fr.inrae.agroclim.indicators.model.criteria.NoCriteria; import fr.inrae.agroclim.indicators.model.criteria.SimpleCriteria; import fr.inrae.agroclim.indicators.model.data.DataTestHelper; @@ -67,7 +66,7 @@ public class FrequencyTest extends DataTestHelper { String error = null; try { result = indicator.computeSingleValue(climaticData); - } catch (TechnicalException | FunctionalException ex) { + } catch (final IndicatorsException ex) { error = ex.getClass().getCanonicalName() + " : " + ex.getMessage(); } assertTrue(error, error == null); @@ -76,7 +75,7 @@ public class FrequencyTest extends DataTestHelper { nbOfDays.setCriteria(new NoCriteria()); try { result = indicator.computeSingleValue(climaticData); - } catch (TechnicalException | FunctionalException ex) { + } catch (final IndicatorsException ex) { error = ex.getClass().getCanonicalName() + " : " + ex.getMessage(); } assertTrue(error, error == null); diff --git a/src/test/java/fr/inrae/agroclim/indicators/model/indicator/IndicatorTest.java b/src/test/java/fr/inrae/agroclim/indicators/model/indicator/IndicatorTest.java index b70220dd..78db4252 100644 --- a/src/test/java/fr/inrae/agroclim/indicators/model/indicator/IndicatorTest.java +++ b/src/test/java/fr/inrae/agroclim/indicators/model/indicator/IndicatorTest.java @@ -27,7 +27,7 @@ import java.util.Set; import org.junit.BeforeClass; import org.junit.Test; -import fr.inrae.agroclim.indicators.exception.FunctionalException; +import fr.inrae.agroclim.indicators.exception.IndicatorsException; import fr.inrae.agroclim.indicators.exception.TechnicalException; import fr.inrae.agroclim.indicators.model.EvaluationType; import fr.inrae.agroclim.indicators.model.Knowledge; @@ -54,8 +54,7 @@ public class IndicatorTest extends DataTestHelper { private static final long serialVersionUID = 1L; @Override - public Double compute(final Resource<? extends DailyData> data) - throws TechnicalException, FunctionalException { + public Double compute(final Resource<? extends DailyData> data) throws IndicatorsException { throw new UnsupportedOperationException("Not supported yet."); } @@ -107,7 +106,7 @@ public class IndicatorTest extends DataTestHelper { @Override public void removeParameter(final Parameter param) { throw new UnsupportedOperationException("Not supported yet."); - + } } diff --git a/src/test/java/fr/inrae/agroclim/indicators/model/indicator/MaxWaveLengthTest.java b/src/test/java/fr/inrae/agroclim/indicators/model/indicator/MaxWaveLengthTest.java index 88867844..12912701 100644 --- a/src/test/java/fr/inrae/agroclim/indicators/model/indicator/MaxWaveLengthTest.java +++ b/src/test/java/fr/inrae/agroclim/indicators/model/indicator/MaxWaveLengthTest.java @@ -5,8 +5,7 @@ import static org.junit.Assert.assertTrue; import org.junit.Test; -import fr.inrae.agroclim.indicators.exception.FunctionalException; -import fr.inrae.agroclim.indicators.exception.TechnicalException; +import fr.inrae.agroclim.indicators.exception.IndicatorsException; import fr.inrae.agroclim.indicators.model.criteria.Criteria; import fr.inrae.agroclim.indicators.model.criteria.RelationalOperator; import fr.inrae.agroclim.indicators.model.criteria.SimpleCriteria; @@ -53,7 +52,7 @@ public class MaxWaveLengthTest extends DataTestHelper { String error = null; try { result = instance.computeSingleValue(climaticData); - } catch (TechnicalException | FunctionalException ex) { + } catch (final IndicatorsException ex) { error = ex.getClass().getCanonicalName() + " : " + ex.getMessage(); } assertTrue(error, error == null); @@ -77,7 +76,7 @@ public class MaxWaveLengthTest extends DataTestHelper { String error = null; try { result = instance.computeSingleValue(climaticData); - } catch (TechnicalException | FunctionalException ex) { + } catch (final IndicatorsException ex) { error = ex.getClass().getCanonicalName() + " : " + ex.getMessage(); } assertTrue(error, error == null); @@ -86,17 +85,11 @@ public class MaxWaveLengthTest extends DataTestHelper { /** * Without criteria: raise exception. + * @throws IndicatorsException expected exception while compute */ - @Test(expected = RuntimeException.class) - public void withoutCriteria() { + @Test(expected = IndicatorsException.class) + public void withoutCriteria() throws IndicatorsException { final MaxWaveLength instance = new MaxWaveLength(); - - String error = null; - try { - instance.computeSingleValue(climaticData); - } catch (TechnicalException | FunctionalException ex) { - error = ex.getClass().getCanonicalName() + " : " + ex.getMessage(); - } - assertTrue(error, error == null); + instance.computeSingleValue(climaticData); } } diff --git a/src/test/java/fr/inrae/agroclim/indicators/model/indicator/NumberOfDaysTest.java b/src/test/java/fr/inrae/agroclim/indicators/model/indicator/NumberOfDaysTest.java index 9b4dba30..4ad1a5d1 100644 --- a/src/test/java/fr/inrae/agroclim/indicators/model/indicator/NumberOfDaysTest.java +++ b/src/test/java/fr/inrae/agroclim/indicators/model/indicator/NumberOfDaysTest.java @@ -21,8 +21,7 @@ import static org.junit.Assert.assertTrue; import org.junit.Test; -import fr.inrae.agroclim.indicators.exception.FunctionalException; -import fr.inrae.agroclim.indicators.exception.TechnicalException; +import fr.inrae.agroclim.indicators.exception.IndicatorsException; import fr.inrae.agroclim.indicators.model.criteria.ComparisonCriteria; import fr.inrae.agroclim.indicators.model.criteria.Criteria; import fr.inrae.agroclim.indicators.model.criteria.RelationalOperator; @@ -73,7 +72,7 @@ public final class NumberOfDaysTest extends DataTestHelper { String error = null; try { result = instance.compute(climaticData); - } catch (TechnicalException | FunctionalException ex) { + } catch (final IndicatorsException ex) { error = ex.getClass().getCanonicalName() + " : " + ex.getMessage(); } assertTrue(error, error == null); @@ -93,7 +92,7 @@ public final class NumberOfDaysTest extends DataTestHelper { String error = null; try { result = instance.computeSingleValue(climaticData); - } catch (TechnicalException | FunctionalException ex) { + } catch (final IndicatorsException ex) { error = ex.getClass().getCanonicalName() + " : " + ex.getMessage(); } assertTrue(error, error == null); @@ -114,7 +113,7 @@ public final class NumberOfDaysTest extends DataTestHelper { String error = null; try { result = instance.computeSingleValue(climaticData); - } catch (TechnicalException | FunctionalException ex) { + } catch (final IndicatorsException ex) { error = ex.getClass().getCanonicalName() + " : " + ex.getMessage(); } assertTrue(error, error == null); @@ -133,7 +132,7 @@ public final class NumberOfDaysTest extends DataTestHelper { String error = null; try { result = instance.computeSingleValue(climaticData); - } catch (TechnicalException | FunctionalException ex) { + } catch (final IndicatorsException ex) { error = ex.getClass().getCanonicalName() + " : " + ex.getMessage(); } assertTrue(error, error == null); diff --git a/src/test/java/fr/inrae/agroclim/indicators/model/indicator/NumberOfWavesTest.java b/src/test/java/fr/inrae/agroclim/indicators/model/indicator/NumberOfWavesTest.java index 368d348e..1e993f07 100644 --- a/src/test/java/fr/inrae/agroclim/indicators/model/indicator/NumberOfWavesTest.java +++ b/src/test/java/fr/inrae/agroclim/indicators/model/indicator/NumberOfWavesTest.java @@ -23,8 +23,7 @@ import static org.junit.Assert.assertTrue; import org.junit.Test; -import fr.inrae.agroclim.indicators.exception.FunctionalException; -import fr.inrae.agroclim.indicators.exception.TechnicalException; +import fr.inrae.agroclim.indicators.exception.IndicatorsException; import fr.inrae.agroclim.indicators.model.criteria.Criteria; import fr.inrae.agroclim.indicators.model.criteria.RelationalOperator; import fr.inrae.agroclim.indicators.model.criteria.SimpleCriteria; @@ -75,7 +74,7 @@ public final class NumberOfWavesTest extends DataTestHelper { String error = null; try { result = instance.computeSingleValue(climaticData); - } catch (TechnicalException | FunctionalException ex) { + } catch (final IndicatorsException ex) { error = ex.getClass().getCanonicalName() + " : " + ex.getMessage(); } assertTrue(error, error == null); @@ -84,17 +83,11 @@ public final class NumberOfWavesTest extends DataTestHelper { /** * Without criteria: raise exception. + * @throws IndicatorsException expected exception while compute */ - @Test(expected = RuntimeException.class) - public void withoutCriteria() { + @Test(expected = IndicatorsException.class) + public void withoutCriteria() throws IndicatorsException { final NumberOfWaves instance = new NumberOfWaves(); - - String error = null; - try { - instance.computeSingleValue(climaticData); - } catch (TechnicalException | FunctionalException ex) { - error = ex.getClass().getCanonicalName() + " : " + ex.getMessage(); - } - assertTrue(error, error == null); + instance.computeSingleValue(climaticData); } } diff --git a/src/test/java/fr/inrae/agroclim/indicators/model/indicator/PhaseLengthTest.java b/src/test/java/fr/inrae/agroclim/indicators/model/indicator/PhaseLengthTest.java index 60c03cd3..72dad372 100644 --- a/src/test/java/fr/inrae/agroclim/indicators/model/indicator/PhaseLengthTest.java +++ b/src/test/java/fr/inrae/agroclim/indicators/model/indicator/PhaseLengthTest.java @@ -18,8 +18,7 @@ */ package fr.inrae.agroclim.indicators.model.indicator; -import fr.inrae.agroclim.indicators.exception.FunctionalException; -import fr.inrae.agroclim.indicators.exception.TechnicalException; +import fr.inrae.agroclim.indicators.exception.IndicatorsException; import fr.inrae.agroclim.indicators.model.data.DataTestHelper; import fr.inrae.agroclim.indicators.model.data.climate.ClimaticResource; import static junit.framework.TestCase.assertEquals; @@ -62,7 +61,7 @@ public class PhaseLengthTest extends DataTestHelper { String error = null; try { result = indicator.computeSingleValue(climaticData); - } catch (TechnicalException | FunctionalException ex) { + } catch (IndicatorsException ex) { error = ex.getClass().getCanonicalName() + " : " + ex.getMessage(); } assertTrue(error, error == null); diff --git a/src/test/java/fr/inrae/agroclim/indicators/model/indicator/PhotothermalQuotientTest.java b/src/test/java/fr/inrae/agroclim/indicators/model/indicator/PhotothermalQuotientTest.java index 2a648659..a38ca0fb 100644 --- a/src/test/java/fr/inrae/agroclim/indicators/model/indicator/PhotothermalQuotientTest.java +++ b/src/test/java/fr/inrae/agroclim/indicators/model/indicator/PhotothermalQuotientTest.java @@ -23,8 +23,7 @@ import static org.junit.Assert.assertNotEquals; import org.junit.Test; -import fr.inrae.agroclim.indicators.exception.FunctionalException; -import fr.inrae.agroclim.indicators.exception.TechnicalException; +import fr.inrae.agroclim.indicators.exception.IndicatorsException; import fr.inrae.agroclim.indicators.model.criteria.RelationalOperator; import fr.inrae.agroclim.indicators.model.criteria.SimpleCriteria; import fr.inrae.agroclim.indicators.model.data.DataTestHelper; @@ -77,7 +76,7 @@ public class PhotothermalQuotientTest extends DataTestHelper { } @Test - public void computeSingleValue() throws TechnicalException, FunctionalException { + public void computeSingleValue() throws IndicatorsException { final Double radiationSum = climaticData.getData().stream().map(ClimaticDailyData::getRadiation) .reduce(0d, Double::sum); final Double tmeanSum = climaticData.getData().stream().map(ClimaticDailyData::getTmean) @@ -89,7 +88,7 @@ public class PhotothermalQuotientTest extends DataTestHelper { } @Test - public void withNormalization() throws TechnicalException, FunctionalException { + public void withNormalization() throws IndicatorsException { indicator.getDividend().setNormalizationFunction(new Sigmoid()); indicator.getDivisor().setNormalizationFunction(new Sigmoid()); final double actual = indicator.computeSingleValue(climaticData); diff --git a/src/test/java/fr/inrae/agroclim/indicators/model/indicator/QuotientTest.java b/src/test/java/fr/inrae/agroclim/indicators/model/indicator/QuotientTest.java index c7d1b503..e2b255cd 100644 --- a/src/test/java/fr/inrae/agroclim/indicators/model/indicator/QuotientTest.java +++ b/src/test/java/fr/inrae/agroclim/indicators/model/indicator/QuotientTest.java @@ -21,8 +21,7 @@ import static org.junit.Assert.assertTrue; import org.junit.Test; -import fr.inrae.agroclim.indicators.exception.FunctionalException; -import fr.inrae.agroclim.indicators.exception.TechnicalException; +import fr.inrae.agroclim.indicators.exception.IndicatorsException; import fr.inrae.agroclim.indicators.model.criteria.Criteria; import fr.inrae.agroclim.indicators.model.criteria.RelationalOperator; import fr.inrae.agroclim.indicators.model.criteria.SimpleCriteria; @@ -77,7 +76,7 @@ public final class QuotientTest extends DataTestHelper { String error = null; try { result = indicator.computeSingleValue(climaticData); - } catch (TechnicalException | FunctionalException ex) { + } catch (IndicatorsException ex) { error = ex.getClass().getCanonicalName() + " : " + ex.getMessage(); } assertTrue(error, error == null); @@ -97,7 +96,7 @@ public final class QuotientTest extends DataTestHelper { String error = null; try { result = ind.computeSingleValue(climaticData); - } catch (TechnicalException | FunctionalException ex) { + } catch (IndicatorsException ex) { error = ex.getClass().getCanonicalName() + " : " + ex.getMessage(); } double expected = 10d; diff --git a/src/test/java/fr/inrae/agroclim/indicators/model/indicator/SumTest.java b/src/test/java/fr/inrae/agroclim/indicators/model/indicator/SumTest.java index 65465aa4..31e2e51e 100644 --- a/src/test/java/fr/inrae/agroclim/indicators/model/indicator/SumTest.java +++ b/src/test/java/fr/inrae/agroclim/indicators/model/indicator/SumTest.java @@ -5,8 +5,7 @@ import static org.junit.Assert.assertNull; import org.junit.Test; -import fr.inrae.agroclim.indicators.exception.FunctionalException; -import fr.inrae.agroclim.indicators.exception.TechnicalException; +import fr.inrae.agroclim.indicators.exception.IndicatorsException; import fr.inrae.agroclim.indicators.model.criteria.NoCriteria; import fr.inrae.agroclim.indicators.model.criteria.SimpleCriteria; import fr.inrae.agroclim.indicators.model.data.DataTestHelper; @@ -53,7 +52,7 @@ public class SumTest extends DataTestHelper { String error = null; try { result = indicator.computeSingleValue(climaticData); - } catch (TechnicalException | FunctionalException ex) { + } catch (final IndicatorsException ex) { error = ex.getClass().getCanonicalName() + " : " + ex.getMessage(); } assertNull(error, error); @@ -79,7 +78,7 @@ public class SumTest extends DataTestHelper { String error = null; try { result = indicator.computeSingleValue(climaticData); - } catch (TechnicalException | FunctionalException ex) { + } catch (final IndicatorsException ex) { error = ex.getClass().getCanonicalName() + " : " + ex.getMessage(); } assertNull(error, error); -- GitLab From b309dc4b3e85d704476e15f315fe0269955f8447 Mon Sep 17 00:00:00 2001 From: Olivier Maury <Olivier.Maury@inrae.fr> Date: Thu, 21 Dec 2023 11:43:15 +0100 Subject: [PATCH 03/20] Continuer --- .gitlab-ci.yml | 12 +- .../indicators/exception/ErrorCategory.java | 7 +- .../exception/IndicatorsErrorCategory.java | 13 +- .../exception/type/CommonErrorType.java | 46 +++++++ .../exception/type/ComputationErrorType.java | 112 ++++++++++++----- .../exception/type/ResourceErrorType.java | 117 +++++++++--------- .../exception/type/XmlErrorType.java | 49 ++++++++ .../indicators/model/EvaluationSettings.java | 11 +- .../agroclim/indicators/model/Knowledge.java | 21 ++-- .../model/data/ResourceManager.java | 2 +- .../model/indicator/AggregationIndicator.java | 6 +- .../agroclim/indicators/xml/XMLUtil.java | 49 ++++---- .../indicators/resources/messages.properties | 70 +++++++---- .../resources/messages_fr.properties | 57 +++++---- .../exception/ErrorMessageTest.java | 12 +- .../indicators/exception/ErrorTypeTest.java | 3 +- .../model/EvaluationSettingsTest.java | 3 +- .../EvaluationWithoutAggregationTest.java | 6 +- .../indicators/model/KnowledgeDailyTest.java | 7 +- .../indicators/model/KnowledgeHourlyTest.java | 4 +- .../indicators/model/KnowledgeTest.java | 18 +-- .../indicators/model/RaidayMeantTest.java | 3 +- .../model/StageDeltaEvaluationTest.java | 3 +- .../model/criteria/FormulaCriteriaTest.java | 3 +- .../model/criteria/SimpleCriteriaTest.java | 7 +- .../indicators/model/data/DataTestHelper.java | 4 +- .../model/data/ResourceManagerTest.java | 2 +- .../model/data/climate/ClimateTest.java | 6 +- .../data/phenology/PhenologyLoaderTest.java | 6 +- .../model/data/soil/SoilCalculatorTest.java | 4 +- .../model/indicator/AverageTest.java | 3 +- .../model/indicator/DiffOfSumTest.java | 5 +- .../model/indicator/ImplementationsTest.java | 4 +- .../model/indicator/IndicatorTest.java | 7 +- .../model/indicator/TammFormulaTest.java | 4 +- .../listener/CompositeIndicatorTest.java | 4 +- .../listener/PropertyChangeListenerTest.java | 4 +- .../agroclim/indicators/xml/XMLUtilTest.java | 19 ++- 38 files changed, 455 insertions(+), 258 deletions(-) create mode 100644 src/main/java/fr/inrae/agroclim/indicators/exception/type/CommonErrorType.java create mode 100644 src/main/java/fr/inrae/agroclim/indicators/exception/type/XmlErrorType.java diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index d4d6140b..36caf5f4 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -18,7 +18,7 @@ cache: build_job: stage: build - script: + script: - echo "Maven compile started" - mvn compile test-compile - ls -lha /usr/bin/tokei @@ -26,9 +26,15 @@ build_job: test_job: stage: test - script: + script: - echo "Maven test started" - mvn test + artifacts: + when: always + reports: + junit: + - target/surefire-reports/TEST-*.xml + - target/failsafe-reports/TEST-*.xml checkstyle_job: stage: checkstyle @@ -47,7 +53,7 @@ cpd_job: package_job: stage: package - script: + script: - echo "Maven packaging started" - mvn package -DskipTests diff --git a/src/main/java/fr/inrae/agroclim/indicators/exception/ErrorCategory.java b/src/main/java/fr/inrae/agroclim/indicators/exception/ErrorCategory.java index fa2ed983..201e2c1e 100644 --- a/src/main/java/fr/inrae/agroclim/indicators/exception/ErrorCategory.java +++ b/src/main/java/fr/inrae/agroclim/indicators/exception/ErrorCategory.java @@ -17,7 +17,7 @@ public interface ErrorCategory { * @return category description for the category code in I18n */ default String getCategory(final I18n i18n) { - return i18n.get("error.category." + getCode()); + return i18n.get("error.category." + getName().toLowerCase()); } /** @@ -25,4 +25,9 @@ public interface ErrorCategory { */ String getCode(); + /** + * @return short name, formatted as enum name. + */ + String getName(); + } diff --git a/src/main/java/fr/inrae/agroclim/indicators/exception/IndicatorsErrorCategory.java b/src/main/java/fr/inrae/agroclim/indicators/exception/IndicatorsErrorCategory.java index 3292bb30..1e25aa3a 100644 --- a/src/main/java/fr/inrae/agroclim/indicators/exception/IndicatorsErrorCategory.java +++ b/src/main/java/fr/inrae/agroclim/indicators/exception/IndicatorsErrorCategory.java @@ -18,14 +18,18 @@ import lombok.RequiredArgsConstructor; */ @RequiredArgsConstructor public enum IndicatorsErrorCategory implements ErrorCategory { + /** + * While loading XML. + */ + XML("IND01"), /** * For {@link ResourceManager}. */ - RESOURCES("IND01"), + RESOURCES("IND02"), /** * While {@link Indicator#compute()}. */ - COMPUTATION("IND02"); + COMPUTATION("IND03"); /** * Category code: prefix for {@link ErrorType#getFullCode()}. @@ -33,4 +37,9 @@ public enum IndicatorsErrorCategory implements ErrorCategory { @Getter private final String code; + @Override + public String getName() { + return name(); + } + } diff --git a/src/main/java/fr/inrae/agroclim/indicators/exception/type/CommonErrorType.java b/src/main/java/fr/inrae/agroclim/indicators/exception/type/CommonErrorType.java new file mode 100644 index 00000000..67e89b0e --- /dev/null +++ b/src/main/java/fr/inrae/agroclim/indicators/exception/type/CommonErrorType.java @@ -0,0 +1,46 @@ +package fr.inrae.agroclim.indicators.exception.type; + +import fr.inrae.agroclim.indicators.exception.ErrorType; +import java.util.StringJoiner; + +/** + * Common methods to implements ErrorType. + * + * @author Olivier Maury + */ +public interface CommonErrorType extends ErrorType { + /** + * @return partial I18n key for messages.properties + */ + private String getShortKey() { + return getName().toLowerCase().replace("_", "."); + } + + CommonErrorType getParent(); + + String name(); + + /** + * @return Key for Resource/I18nResource. + */ + @Override + default String getI18nKey() { + final String cat = getCategory().getName().toLowerCase(); + final StringJoiner sj = new StringJoiner(".", "error.", ""); + if (!getShortKey().startsWith(cat)) { + sj.add(cat); + } + if (getParent() != null) { + if (!getShortKey().startsWith(getParent().getShortKey())) { + sj.add(getParent().getShortKey()); + } + } + sj.add(getShortKey()); + return sj.toString(); + } + + @Override + default String getName() { + return name(); + } +} diff --git a/src/main/java/fr/inrae/agroclim/indicators/exception/type/ComputationErrorType.java b/src/main/java/fr/inrae/agroclim/indicators/exception/type/ComputationErrorType.java index c940efa6..3c3a79d0 100644 --- a/src/main/java/fr/inrae/agroclim/indicators/exception/type/ComputationErrorType.java +++ b/src/main/java/fr/inrae/agroclim/indicators/exception/type/ComputationErrorType.java @@ -1,7 +1,6 @@ package fr.inrae.agroclim.indicators.exception.type; import fr.inrae.agroclim.indicators.exception.ErrorCategory; -import fr.inrae.agroclim.indicators.exception.ErrorType; import fr.inrae.agroclim.indicators.exception.IndicatorsErrorCategory; import fr.inrae.agroclim.indicators.model.indicator.CompositeIndicator; import lombok.Getter; @@ -9,73 +8,144 @@ import lombok.RequiredArgsConstructor; /** * Keys from messages.properties used to warn about errors in {@link Indicator#compute()}. + * + * @author Olivier Maury */ @RequiredArgsConstructor -public enum ComputationErrorType implements ErrorType { +public enum ComputationErrorType implements CommonErrorType { /** * Definition of the indicator is not good. + * + * Parameter 1 : explaination. */ WRONG_DEFINITION(null, "001"), /** - * When an indicator fails to compute. + * When input causes an exception. + * + * No parameter. */ - COMPUTATION(null, "100"), + INPUT(null, "100"), /** * When an indicator in a {@link CompositeIndicator} fails to compute. + * + * Parameter 1 : indicator id. */ - COMPOSITE_COMPUTATION(COMPUTATION, "101"), + COMPOSITE_COMPUTATION(INPUT, "101"), /** * Criteria should be NoCriteria or SimpleCriteria. + * + * Parameter 1 : indicator id. */ CRITERIA_ISNT_NOCRITERIA_SIMPLECRITERIA(WRONG_DEFINITION, "002"), /** * Criteria should not be null. + * + * No parameter. */ CRITERIA_NULL(WRONG_DEFINITION, "003"), /** * Daily data must not be null. + * + * No parameter. */ - DATA_NULL(COMPUTATION, "113"), + DATA_NULL(INPUT, "113"), /** * Dividend indicator should never be null. + * + * No parameter. */ QUOTIENT_DIVIDEND_NULL(WRONG_DEFINITION, "005"), /** * Computation of dividend failed. + * + * Parameter 1 : indicator id. */ - QUOTIENT_DIVIDEND_EXCEPTION(COMPUTATION, "110"), + QUOTIENT_DIVIDEND_EXCEPTION(INPUT, "110"), /** * Computation of divisor failed. + * + * Parameter 1 : indicator id. */ - QUOTIENT_DIVISOR_EXCEPTION(COMPUTATION, "111"), + QUOTIENT_DIVISOR_EXCEPTION(INPUT, "111"), /** * Cannot compute quotient as result of divisor is zero. + * + * Parameter 1 : indicator id. */ - QUOTIENT_DIVISOR_ZERO(COMPUTATION, "112"), + QUOTIENT_DIVISOR_ZERO(INPUT, "112"), /** * Divisor indicator should never be null. + * + * No parameter. */ QUOTIENT_DIVISOR_NULL(WRONG_DEFINITION, "006"), + /** + * Execution of formula failed. + * + * parameter 1 : expression + */ FORMULA(null, "200"), + /** + * Agregation to apply must not be null. + * + * No parameter. + */ FORMULA_AGGREGATION_NULL(FORMULA, "211"), + /** + * Formula expression must not be null. + * + * No parameter. + */ FORMULA_EXPRESSION_NULL(FORMULA, "221"), + /** + * Formula expression must not be blank. + * + * No parameter. + */ FORMULA_EXPRESSION_BLANK(FORMULA, "222"), + /** + * Parsing error due to missing parenthesis. + * + * parameter 1 : expression + */ FORMULA_EXPRESSION_PARENTHESIS(FORMULA, "223"), + /** + * Parsing error. + * + * parameter 1 : expression + */ FORMULA_EXPRESSION_PARSING(FORMULA, "224"), + /** + * Unknown function. + * + * parameter 1 : expression + * parameter 2 : function + */ FORMULA_FUNCTION_UNKNOWN(FORMULA, "231"), + /** + * Unknown variable. + * + * parameter 1 : expression + * parameter 2 : variable + */ FORMULA_VARIABLE_UNDEFINED(FORMULA, "241"), /** * Threshold must not be null. + * + * No parameter. */ THRESHOLD_NULL(WRONG_DEFINITION, "004"), /** - * Variable must not be null. + * Variable name must not be null. */ VARIABLE_NAME_NULL(WRONG_DEFINITION, "007"), /** * Value for the variable must not be null. + * + * parameter 1 : date + * parameter 2 : variable name */ - VARIABLE_VALUE_NULL(COMPUTATION, "114"); + VARIABLE_VALUE_NULL(INPUT, "114"); /** * Parent refers to the resource part. @@ -93,25 +163,5 @@ public enum ComputationErrorType implements ErrorType { public ErrorCategory getCategory() { return IndicatorsErrorCategory.COMPUTATION; } - /** - * @return partial I18n key for messages.properties - */ - private String getShortKey() { - return name().toLowerCase().replace("_", "."); - } - /** - * @return Key for Resource/I18nResource. - */ - @Override - public String getI18nKey() { - if (parent != null) { - return "error.computation." + parent.getShortKey() + "." + getShortKey(); - } - return "error.computation." + getShortKey(); - } - @Override - public String getName() { - return name(); - } } diff --git a/src/main/java/fr/inrae/agroclim/indicators/exception/type/ResourceErrorType.java b/src/main/java/fr/inrae/agroclim/indicators/exception/type/ResourceErrorType.java index 6e1f6074..09631ddb 100644 --- a/src/main/java/fr/inrae/agroclim/indicators/exception/type/ResourceErrorType.java +++ b/src/main/java/fr/inrae/agroclim/indicators/exception/type/ResourceErrorType.java @@ -1,91 +1,124 @@ package fr.inrae.agroclim.indicators.exception.type; import fr.inrae.agroclim.indicators.exception.ErrorCategory; -import fr.inrae.agroclim.indicators.exception.ErrorType; import fr.inrae.agroclim.indicators.exception.IndicatorsErrorCategory; import lombok.Getter; +import lombok.RequiredArgsConstructor; /** * Keys from messages.properties used to warn about errors in {@link ResourceManager}. + * + * @author Olivier Maury */ -public enum ResourceErrorType implements ErrorType { +@RequiredArgsConstructor +public enum ResourceErrorType implements CommonErrorType { /** * Climate, topic. + * + * No parameter. */ - CLIMATE("100", null, "resource.climatic"), + CLIMATE("100", null), /** * No climate data. + * + * No parameter. + */ + CLIMATE_EMPTY("110", CLIMATE), + /** + * No climate data for the phase. + * + * parameter 0 : start stage name parameter 1 : end stage name parameter 2 : start stage day parameter 3 : end stage + * day parameter 4 : year parameter 5 : first available day parameter 6 ! last available day */ - CLIMATE_EMPTY("110", CLIMATE, "empty"), - CLIMATE_EMPTY_FOR_PHASE("111", CLIMATE_EMPTY, "for.phase"), + CLIMATE_EMPTY_FOR_PHASE("111", CLIMATE_EMPTY), /** * Not enough data. + * + * No parameter. */ - CLIMATE_SIZE_WRONG("101", CLIMATE, "size.wrong"), + CLIMATE_SIZE_WRONG("101", CLIMATE), /** * Years of climate, topic. + * + * No parameter. */ - CLIMATIC_YEARS("120", null, "resource.climatic.years"), + CLIMATE_YEARS("120", null), /** * No years of climate. + * + * No parameter. */ - CLIMATE_YEARS_EMPTY("121", CLIMATIC_YEARS, "empty"), + CLIMATE_YEARS_EMPTY("121", CLIMATE_YEARS), /** * Not enough data. + * + * No parameter. */ - CLIMATE_YEARS_MISSING("122", CLIMATIC_YEARS, "missing"), + CLIMATE_YEARS_MISSING("122", CLIMATE_YEARS), /** * Phenology, topic. + * + * No parameter. */ - PHENO("200", null, "resource.pheno"), + PHENO("200", null), /** * No phenological data. + * + * No parameter. */ - PHENO_EMPTY("201", PHENO, "empty"), + PHENO_EMPTY("201", PHENO), /** * Years of phenology, topic. + * + * No parameter. */ - PHENO_YEARS("210", null, "resource.pheno.years"), + PHENO_YEARS("210", PHENO), /** * No years of phenology. + * + * No parameter. */ - PHENO_YEARS_EMPTY("211", PHENO_YEARS, "empty"), - /** - * Not enough data. - */ - PHENO_YEARS_MISSING("212", PHENO_YEARS, "missing"), + PHENO_YEARS_EMPTY("211", PHENO_YEARS), /** * Resource in general, topic. */ - RESOURCE("001", null, "resource"), + RESOURCES("001", null), /** * Setting not set. + * + * No parameter. */ - RESOURCE_CROPDEVELOPMENT_YEARS("002", RESOURCE, "cropdevelopmentyears.null"), + RESOURCES_CROPDEVELOPMENT_YEARS("002", RESOURCES), /** * Soil, topic. + * + * No parameter. */ - SOIL("300", null, "resource.soil"), + SOIL("300", null), /** * Not enough data. + * + * No parameter. */ - SOIL_SIZE_WRONG("301", SOIL, "size.wrong"), + SOIL_SIZE_WRONG("301", SOIL), /** * Variables, topic. + * + * No parameter. */ - VARIABLES("400", null, "resource.variables"), + VARIABLES("400", null), /** * No variable. + * + * No parameter. */ - VARIABLES_EMPTY("401", VARIABLES, "empty"), + VARIABLES_EMPTY("401", VARIABLES), /** * No variale. + * + * No parameter. */ - VARIABLES_MISSING("402", VARIABLES, "missing"); - /** - * Key for Resource/I18nResource. - */ - private final String key; + VARIABLES_MISSING("402", VARIABLES); /** * Subcode for the error. */ @@ -97,37 +130,9 @@ public enum ResourceErrorType implements ErrorType { @Getter private final ResourceErrorType parent; - /** - * Constructor. - * - * @param c Subcode for the error. - * @param p Parent refers to the resource part. - * @param k Key for Resource/I18nResource. - */ - ResourceErrorType(final String c, final ResourceErrorType p, final String k) { - parent = p; - key = k; - subCode = c; - } - @Override public ErrorCategory getCategory() { return IndicatorsErrorCategory.RESOURCES; } - /** - * @return Key for Resource/I18nResource. - */ - @Override - public String getI18nKey() { - if (parent != null) { - return "error.evaluation." + parent.key + "." + key; - } - return "error.evaluation." + key; - } - - @Override - public String getName() { - return name(); - } } diff --git a/src/main/java/fr/inrae/agroclim/indicators/exception/type/XmlErrorType.java b/src/main/java/fr/inrae/agroclim/indicators/exception/type/XmlErrorType.java new file mode 100644 index 00000000..aba636aa --- /dev/null +++ b/src/main/java/fr/inrae/agroclim/indicators/exception/type/XmlErrorType.java @@ -0,0 +1,49 @@ +package fr.inrae.agroclim.indicators.exception.type; + +import fr.inrae.agroclim.indicators.exception.ErrorCategory; +import fr.inrae.agroclim.indicators.exception.IndicatorsErrorCategory; +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +/** + * Keys from messages.properties used to warn about errors in {@link Indicator#compute()}. + * + * @author Olivier Maury + */ +@RequiredArgsConstructor +public enum XmlErrorType implements CommonErrorType { + /** + * XML file not found. + * + * Parameter 0 : file path + */ + FILE_NOT_FOUND(null, "001"), + /** + * Unable to load. + * + * No parameter. + */ + UNABLE_TO_LOAD(null, "002"), + /** + * Unable to serialize. + * + * No parameter. + */ + UNABLE_TO_SERIALIZE(null, "003"); + /** + * Parent refers to the resource part. + */ + @Getter + private final XmlErrorType parent; + + /** + * Subcode for the error. + */ + @Getter + private final String subCode; + + @Override + public ErrorCategory getCategory() { + return IndicatorsErrorCategory.XML; + } +} diff --git a/src/main/java/fr/inrae/agroclim/indicators/model/EvaluationSettings.java b/src/main/java/fr/inrae/agroclim/indicators/model/EvaluationSettings.java index 47934cd8..1c26ae7c 100644 --- a/src/main/java/fr/inrae/agroclim/indicators/model/EvaluationSettings.java +++ b/src/main/java/fr/inrae/agroclim/indicators/model/EvaluationSettings.java @@ -16,6 +16,7 @@ */ package fr.inrae.agroclim.indicators.model; +import fr.inrae.agroclim.indicators.exception.IndicatorsException; import java.io.Serializable; import java.nio.file.Path; import java.nio.file.Paths; @@ -35,7 +36,6 @@ import javax.xml.bind.annotation.XmlTransient; import javax.xml.bind.annotation.XmlType; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; -import fr.inrae.agroclim.indicators.exception.TechnicalException; import fr.inrae.agroclim.indicators.model.criteria.ComparisonCriteria; import fr.inrae.agroclim.indicators.model.criteria.CompositeCriteria; import fr.inrae.agroclim.indicators.model.criteria.FormulaCriteria; @@ -289,13 +289,10 @@ public final class EvaluationSettings implements Cloneable, Serializable { /** * Load Knowledge. + * @throws IndicatorsException while loading Knowledge */ - public void initializeKnowledge() { - try { - knowledge = Knowledge.load(timescale); - } catch (final TechnicalException e) { - LOGGER.error("Loading Knowledge failed! {}", e); - } + public void initializeKnowledge() throws IndicatorsException { + knowledge = Knowledge.load(timescale); } /** diff --git a/src/main/java/fr/inrae/agroclim/indicators/model/Knowledge.java b/src/main/java/fr/inrae/agroclim/indicators/model/Knowledge.java index 44ed7a05..741c8993 100644 --- a/src/main/java/fr/inrae/agroclim/indicators/model/Knowledge.java +++ b/src/main/java/fr/inrae/agroclim/indicators/model/Knowledge.java @@ -16,6 +16,7 @@ */ package fr.inrae.agroclim.indicators.model; +import fr.inrae.agroclim.indicators.exception.IndicatorsException; import java.io.BufferedWriter; import java.io.IOException; import java.io.InputStream; @@ -41,7 +42,6 @@ import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlElementWrapper; import javax.xml.bind.annotation.XmlRootElement; -import fr.inrae.agroclim.indicators.exception.TechnicalException; import fr.inrae.agroclim.indicators.model.criteria.ComparisonCriteria; import fr.inrae.agroclim.indicators.model.criteria.CompositeCriteria; import fr.inrae.agroclim.indicators.model.criteria.FormulaCriteria; @@ -152,9 +152,9 @@ public final class Knowledge implements Cloneable { * Deserialize Knowledge from embedded file for daily indicators. * * @return deserialized Knowledge - * @throws TechnicalException error while loading knowledge + * @throws IndicatorsException error while loading knowledge */ - public static Knowledge load() throws TechnicalException { + public static Knowledge load() throws IndicatorsException { return load(TimeScale.DAILY); } @@ -164,11 +164,10 @@ public final class Knowledge implements Cloneable { * @param stream * input stream * @return deserialized Knowledge - * @throws TechnicalException + * @throws IndicatorsException * error while loading knowledge */ - private static Knowledge load(final InputStream stream) - throws TechnicalException { + private static Knowledge load(final InputStream stream) throws IndicatorsException { try { final Knowledge knowledge = (Knowledge) XMLUtil.loadResource(stream, CLASSES_FOR_JAXB); @@ -179,7 +178,7 @@ public final class Knowledge implements Cloneable { knowledge.culturalPractices.forEach(ind -> ind.setIndicatorCategory(IndicatorCategory.CULTURAL_PRATICES)); return knowledge; - } catch (final TechnicalException ex) { + } catch (final IndicatorsException ex) { LOGGER.error(ex); throw ex; } @@ -190,19 +189,19 @@ public final class Knowledge implements Cloneable { * * @param timescale timescale of indicators * @return deserialized Knowledge - * @throws TechnicalException error while loading knowledge + * @throws IndicatorsException error while loading knowledge */ - public static Knowledge load(final TimeScale timescale) throws TechnicalException { + public static Knowledge load(final TimeScale timescale) throws IndicatorsException { final InputStream stream = Knowledge.class.getResourceAsStream(RESOURCES.get(timescale)); return load(stream); } /** * @param args not used - * @throws TechnicalException while loading knowledge + * @throws IndicatorsException while loading knowledge * @throws java.io.IOException while writing file */ - public static void main(final String[] args) throws TechnicalException, + public static void main(final String[] args) throws IndicatorsException, IOException { for (final TimeScale timescale: TimeScale.values()) { LOGGER.trace("Generating files for {}...", timescale); diff --git a/src/main/java/fr/inrae/agroclim/indicators/model/data/ResourceManager.java b/src/main/java/fr/inrae/agroclim/indicators/model/data/ResourceManager.java index 6c091cd1..31b74dd2 100644 --- a/src/main/java/fr/inrae/agroclim/indicators/model/data/ResourceManager.java +++ b/src/main/java/fr/inrae/agroclim/indicators/model/data/ResourceManager.java @@ -177,7 +177,7 @@ public final class ResourceManager implements Serializable, Cloneable { return errors; } if (cropDevelopmentYears == null) { - addErrorMessage(errors, ResourceErrorType.RESOURCE_CROPDEVELOPMENT_YEARS); + addErrorMessage(errors, ResourceErrorType.RESOURCES_CROPDEVELOPMENT_YEARS); return errors; } // Phenology data drives evaluation, so diff --git a/src/main/java/fr/inrae/agroclim/indicators/model/indicator/AggregationIndicator.java b/src/main/java/fr/inrae/agroclim/indicators/model/indicator/AggregationIndicator.java index c64f4b32..142912ab 100644 --- a/src/main/java/fr/inrae/agroclim/indicators/model/indicator/AggregationIndicator.java +++ b/src/main/java/fr/inrae/agroclim/indicators/model/indicator/AggregationIndicator.java @@ -91,7 +91,7 @@ public abstract class AggregationIndicator extends SimpleIndicatorWithCriteria i return aggregate(stream); } catch (final RuntimeException ex) { if (ex.getCause() instanceof IndicatorsException iex) { - throw new IndicatorsException(ComputationErrorType.COMPUTATION, iex); + throw iex; } throw ex; } @@ -100,7 +100,9 @@ public abstract class AggregationIndicator extends SimpleIndicatorWithCriteria i @Override public final Criteria getCriteria() { if (super.getCriteria() == null) { - super.setCriteria(new NoCriteria()); + final var criteria = new NoCriteria(); + criteria.setVariable(variable); + super.setCriteria(criteria); } if (super.getCriteria() instanceof VariableCriteria && this.variable != null) { ((VariableCriteria) super.getCriteria()).setVariable(this.variable); diff --git a/src/main/java/fr/inrae/agroclim/indicators/xml/XMLUtil.java b/src/main/java/fr/inrae/agroclim/indicators/xml/XMLUtil.java index c2a52340..3ad157fc 100644 --- a/src/main/java/fr/inrae/agroclim/indicators/xml/XMLUtil.java +++ b/src/main/java/fr/inrae/agroclim/indicators/xml/XMLUtil.java @@ -16,6 +16,7 @@ */ package fr.inrae.agroclim.indicators.xml; +import fr.inrae.agroclim.indicators.exception.IndicatorsException; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; @@ -38,12 +39,11 @@ import org.w3c.dom.ls.LSInput; import org.w3c.dom.ls.LSResourceResolver; import org.xml.sax.SAXException; -import fr.inrae.agroclim.indicators.exception.TechnicalException; +import fr.inrae.agroclim.indicators.exception.type.XmlErrorType; import fr.inrae.agroclim.indicators.model.EvaluationSettings; import fr.inrae.agroclim.indicators.model.Knowledge; import java.io.PrintWriter; import java.io.StringWriter; -import java.util.HashMap; import java.util.Map; import lombok.Getter; import lombok.Setter; @@ -220,10 +220,9 @@ public abstract class XMLUtil { * @return Public ID of doctype → Resource for the doctype file. */ public static Map<String, InputStream> getDtds() { - final Map<String, InputStream> map = new HashMap<>(); - map.put(DTD_PUBLIC_ID_EVALUATION, getResourceAsStream("evaluation.dtd")); - map.put(DTD_PUBLIC_ID_KNOWLEDGE, getResourceAsStream("knowledge.dtd")); - return map; + return Map.of(// + DTD_PUBLIC_ID_EVALUATION, getResourceAsStream("evaluation.dtd"), // + DTD_PUBLIC_ID_KNOWLEDGE, getResourceAsStream("knowledge.dtd")); } /** @@ -244,17 +243,16 @@ public abstract class XMLUtil { * @param clazz * used classes * @return object for the XML file - * @throws TechnicalException + * @throws IndicatorsException * exception from JAXBException */ - public static Object load(final File xmlFile, final Class<?>... clazz) - throws TechnicalException { + public static Object load(final File xmlFile, final Class<?>... clazz) throws IndicatorsException { try (InputStream inputStream = new FileInputStream(xmlFile);) { return loadResource(inputStream, clazz); } catch (final FileNotFoundException ex) { - throw new TechnicalException("File not found " + xmlFile.getAbsolutePath(), ex); + throw new IndicatorsException(XmlErrorType.FILE_NOT_FOUND, ex, xmlFile.getAbsolutePath()); } catch (final IOException ex) { - throw new TechnicalException("Unable to load ", ex); + throw new IndicatorsException(XmlErrorType.UNABLE_TO_LOAD, ex); } } @@ -266,13 +264,12 @@ public abstract class XMLUtil { * @param clazz * used classes * @return object for the XML file - * @throws TechnicalException + * @throws IndicatorsException * exception from JAXBException */ - public static Object loadResource(final InputStream inputStream, final Class<?>... clazz) - throws TechnicalException { + public static Object loadResource(final InputStream inputStream, final Class<?>... clazz) throws IndicatorsException { if (inputStream == null) { - throw new TechnicalException("InputStream should not be null!"); + throw new IndicatorsException(XmlErrorType.FILE_NOT_FOUND, "InputStream should not be null!"); } try { UnmarshallerBuilder builder = new UnmarshallerBuilder(); @@ -287,7 +284,7 @@ public abstract class XMLUtil { final PrintWriter pw = new PrintWriter(buffer); ex.printStackTrace(pw); LOGGER.fatal("Unable to deserialize : {}", buffer); - throw new TechnicalException("Unable to load", ex); + throw new IndicatorsException(XmlErrorType.UNABLE_TO_LOAD, ex); } } @@ -301,15 +298,16 @@ public abstract class XMLUtil { * output stream * @param clazz * used classes - * @throws TechnicalException + * @throws IndicatorsException * exception from JAXBException */ public static void serialize(final Object o, final OutputStream outputStream, final Class<?>... clazz) - throws TechnicalException { + throws IndicatorsException { try (OutputStreamWriter writer = new OutputStreamWriter(outputStream, StandardCharsets.UTF_8);) { serialize(o, writer, clazz); } catch (final IOException ex) { - throw new TechnicalException("Unable to create OutputStreamWriter : " + o, ex); + throw new IndicatorsException(XmlErrorType.UNABLE_TO_SERIALIZE, ex, + "Unable to create OutputStreamWriter : " + o); } } @@ -322,16 +320,17 @@ public abstract class XMLUtil { * file path * @param clazz * used classes - * @throws TechnicalException + * @throws IndicatorsException * exception from JAXBException */ public static void serialize(final Object o, final String fileName, final Class<?>... clazz) - throws TechnicalException { + throws IndicatorsException { try (FileOutputStream stream = new FileOutputStream(fileName);) { serialize(o, new OutputStreamWriter(stream, StandardCharsets.UTF_8), clazz); } catch (final IOException ex) { LOGGER.catching(ex); - throw new TechnicalException("Unable to create FileOutputStream : " + o, ex); + throw new IndicatorsException(XmlErrorType.UNABLE_TO_SERIALIZE, ex, + "Unable to create FileOutputStream : " + o); } } @@ -344,11 +343,11 @@ public abstract class XMLUtil { * writer * @param clazz * used classes - * @throws TechnicalException + * @throws IndicatorsException * exception from JAXBException */ private static void serialize(final Object o, final Writer writer, final Class<?>... clazz) - throws TechnicalException { + throws IndicatorsException { try { final MarshallerBuilder builder = new MarshallerBuilder(); if (o instanceof EvaluationSettings) { @@ -365,7 +364,7 @@ public abstract class XMLUtil { final PrintWriter pw = new PrintWriter(buffer); ex.printStackTrace(pw); LOGGER.fatal("Unable to serialize : " + buffer.toString(), ex); - throw new TechnicalException("Unable to serialize : " + o, ex); + throw new IndicatorsException(XmlErrorType.UNABLE_TO_SERIALIZE, ex); } } diff --git a/src/main/resources/fr/inrae/agroclim/indicators/resources/messages.properties b/src/main/resources/fr/inrae/agroclim/indicators/resources/messages.properties index aed9f283..dc7ffc32 100644 --- a/src/main/resources/fr/inrae/agroclim/indicators/resources/messages.properties +++ b/src/main/resources/fr/inrae/agroclim/indicators/resources/messages.properties @@ -17,31 +17,57 @@ #Errors error.climate.jdbc.query=Error while query execution "{0}"! error.climate.dates=For the year {0}, available dates are from {1} to {2}. -error.climate.missing=No climatic daily data for phase {0}-{1} (days {2} -> {3}) in {4}. error.climate.no.data=No data were retrieved. error.climate.wrong.headers=Wrong number of headers! {0} headers are in the file: {1}, but {2} headers are defined: {3}. error.computation.wrong.definition=The indicator "{0}" is not well defined: {1}. error.computation.wrong.definition.criteria.isnt.nocriteria.simplecriteria=criteria is neither NoCriteria nor SimpleCriteria! error.evaluation.resource=Error for resources! error.evaluation.resource.climatic=Error for climatic data set in resources! -error.evaluation.resource.climatic.empty=No climatic data set in resources! -error.evaluation.resource.climatic.size.wrong=The number of climatic data does not match whole years! -error.evaluation.resource.climatic.years=Error for years in climatic data set in resources! -error.evaluation.resource.climatic.years.empty=No year in climatic data set in resources! -error.evaluation.resource.climatic.years.missing=Climatic data set in resources miss for years {0}! -error.evaluation.resource.cropdevelopmentyears.null=The property ResourceManager.cropDevelopmentYears must not be null! -error.evaluation.resource.pheno=Error for phenological data set in resources! -error.evaluation.resource.pheno.empty=No phenological data set in resources! -error.evaluation.resource.pheno.years=Error for years in phenological data set in resources! -error.evaluation.resource.pheno.years.empty=No year in phenological data set in resources! -error.evaluation.resource.pheno.years.missing=Phenological data set in resources miss for years {0}! -error.evaluation.resource.soil=Error for soil data! -error.evaluation.resource.soil.size.wrong=The number of soil data does not match whole years! -error.evaluation.resource.variables=Error for the property ResourceManager.variables! -error.evaluation.resource.variables.empty=The property ResourceManager.variables must not be empty! -error.evaluation.resource.variables.missing=The property ResourceManager.variables must not be null! +error.computation.formula=Error while executing expression "{0}". +error.computation.formula.aggregation.null=Aggregation must not be null. +error.computation.formula.expression.blank=Expression must not be empty. +error.computation.formula.expression.null=Expression must not be null. +error.computation.formula.expression.parenthesis=Invalid expression "{0}": missing parenthesis. +error.computation.formula.expression.parsing=Invalid expression "{0}": parsing error. +error.computation.formula.function.unknown=Invalid expression "{0}": the function "{1}" is unknown or ambiguous. If the function exists check arguments. +error.computation.formula.variable.undefined=Invalid expression "{0}": the variable "{1}" is not defined. +error.computation.input= +error.computation.input.composite.computation= +error.computation.input.data.null= +error.computation.input.quotient.dividend.exception= +error.computation.input.quotient.divisor.exception= +error.computation.input.quotient.divisor.zero= +error.computation.input.variable.value.null= +error.computation.wrong.definition.criteria.null= +error.computation.wrong.definition.quotient.dividend.null= +error.computation.wrong.definition.quotient.divisor.null= +error.computation.wrong.definition.threshold.null= +error.computation.wrong.definition.variable.name.null= error.day.duplicate={0}: line {1}: this is the same date as previous line "{2}". error.day.missing={0}: line {1}: a day is missing before "{2}". +error.resources.climate= +error.resources= +error.resources.cropdevelopment.years= +error.resources.soil=Error for soil data! +error.resources.soil.size.wrong=The number of soil data does not match whole years! +error.resources.variables=Error for the property ResourceManager.variables! +error.resources.variables.empty=The property ResourceManager.variables must not be empty! +error.resources.variables.missing=The property ResourceManager.variables must not be null! +error.resources.climate.empty.for.phase=No climatic daily data for phase {0}-{1} (from {2} to {3}) in {4}. Available data between {5} and {6}. +error.resources.climate.empty=No climatic data set in resources! +error.resources.climate.size.wrong=The number of climatic data does not match whole years! +error.resources.climate.years.empty=No year in climatic data set in resources! +error.resources.climate.years=Error for years in climatic data set in resources! +error.resources.climate.years.missing=Climatic data set in resources miss for years {0}! +error.resources.cropdevelopmentyears.null=The property ResourceManager.cropDevelopmentYears must not be null! +error.resources.pheno.empty=No phenological data set in resources! +error.resources.pheno=Error for phenological data set in resources! +error.resources.pheno.years.empty=No year in phenological data set in resources! +error.resources.pheno.years=Error for years in phenological data set in resources! +error.resources.pheno.years.missing=Phenological data set in resources miss for years {0}! +error.xml.file.not.found= +error.xml.unable.to.load= +error.xml.unable.to.serialize= error.day.null={0}: line {1}: day is required. error.day.succession={0}: line {1}: the day "{2}" is ealier than the day of the previous line "{3}". error.date.notread=The start and/or end date could not be read @@ -95,14 +121,6 @@ normalization.Sigmoid=Sigmoid EvaluationType.WITH_AGGREGATION.name=with aggregation EvaluationType.WITHOUT_AGGREGATION.name=without aggregation -JEXLFormula.error.execution=Error while executing expression "{0}". -JEXLFormula.error.expression.null=Expression must not be null. -JEXLFormula.error.expression.empty=Expression must not be empty. -JEXLFormula.error.expression.parenthesis=Invalid expression "{0}": missing parenthesis. -JEXLFormula.error.expression.parsing=Invalid expression "{0}": parsing error. -JEXLFormula.error.variable.undefined=Invalid expression "{0}": the variable "{1}" is not defined. -JEXLFormula.error.function.unknown=Invalid expression "{0}": the function "{1}" is unknown or ambiguous. If the function exists check arguments. - MathMethod.avg.description = Returns the average of values passed as function parameter. MathMethod.exp.description = Returns Euler's number e raised to the power of a double value. Special cases:\n\n\ If the argument is NaN, the result is NaN.\n\ @@ -142,4 +160,4 @@ Variable.RAIN.description=Rain precipitation [mm]. Variable.RH.description=Relative humidity [%]. Variable.SOILWATERCONTENT.description=Soil water content [% mass]. Variable.WATER_RESERVE.description=Soil water reserve [mm]. -Variable.WIND.description=Wind speed [m/s]. \ No newline at end of file +Variable.WIND.description=Wind speed [m/s]. diff --git a/src/main/resources/fr/inrae/agroclim/indicators/resources/messages_fr.properties b/src/main/resources/fr/inrae/agroclim/indicators/resources/messages_fr.properties index 46bb1c77..090adcc7 100644 --- a/src/main/resources/fr/inrae/agroclim/indicators/resources/messages_fr.properties +++ b/src/main/resources/fr/inrae/agroclim/indicators/resources/messages_fr.properties @@ -21,27 +21,48 @@ warning.soilcalculator.4stages[one]=Un stade ph\u00e9nologique est fourni, mais warning.soilloader.missing=La configuration pour le calcul du bilan hydrique manque alors que des indicateurs portent sur la teneur en eau du sol ou la r\u00e9serve utile. warning.tmax.inferiorto.tmin={0}\u00a0: ligne {1}\u00a0: la temp\u00e9rature minimale doit \u00eatre inf\u00e9rieure \u00e0 la temp\u00e9rature maximale. error.climate.dates=Pour l\u2019ann\u00e9e {0}, les dates lues vont du {1} au {2}. -error.climate.missing=Aucune donn\u00e9e climatique pour la phase {0}-{1} (jours {2} -> {3}) en {4}. error.climate.no.data=Aucune donn\u00e9e n\u2019a \u00e9t\u00e9 r\u00e9cup\u00e9r\u00e9e. error.climate.wrong.headers=Mauvais nombre d\u2019ent\u00eates\u00a0! {0} ent\u00eates sont dans le fichier : {1}, mais {2} ent\u00eates sont d\u00e9finis : {3}. -error.evaluation.resource=Erreur pour les ressources\u00a0! +error.computation.formula=Erreur lors de l\u2019ex\u00e9cution de l\u2019expression \u00ab {0} \u00bb. +error.computation.formula.aggregation.null=L\u2019agr\u00e9gation ne peut \u00eatre nulle. +error.computation.formula.expression.blank=L\u2019expression ne peut \u00eatre vide. +error.computation.formula.expression.null=L\u2019expression ne peut \u00eatre nulle. +error.computation.formula.expression.parenthesis=Expression non valide \u00ab {0} \u00bb : des parenth\u00e8ses manquent. +error.computation.formula.expression.parsing=Expression non valide \u00ab {0} \u00bb : erreur d\u2019analyse. +error.computation.formula.function.unknown=Expression non valide \u00ab {0} \u00bb : la fonction \u00ab {1} \u00bb est inconnue ou ambig\u00fce. Si la fonction existe, v\u00e9rifiez les arguments. +error.computation.formula.variable.undefined=Expression non valide \u00ab {0} \u00bb : la variable \u00ab {1} \u00bb n\u2019est pas d\u00e9finie. + +error.computation.input= +error.computation.input.composite.computation= +error.computation.input.data.null= +error.computation.input.quotient.dividend.exception= +error.computation.input.quotient.divisor.exception= +error.computation.input.quotient.divisor.zero= +error.computation.input.variable.value.null= +error.computation.wrong.definition.criteria.null= +error.computation.wrong.definition.quotient.dividend.null= +error.computation.wrong.definition.quotient.divisor.null= +error.computation.wrong.definition.threshold.null= +error.computation.wrong.definition.variable.name.null= error.evaluation.resource.climatic=Erreur pour les donn\u00e9es climatiques d\u00e9finies dans les ressources\u00a0! -error.evaluation.resource.climatic.empty=Aucune donn\u00e9e climatique d\u00e9finie dans les ressources\u00a0! -error.evaluation.resource.climatic.size.wrong=Le nombre de donn\u00e9es climatiques ne correspond pas \u00e0 des ann\u00e9es enti\u00e8res\u00a0! -error.evaluation.resource.climatic.years.empty=Erreur pour les ann\u00e9es dans les donn\u00e9es climatiques d\u00e9finies des ressources\u00a0! -error.evaluation.resource.climatic.years.empty=Aucune ann\u00e9e dans les donn\u00e9es climatiques d\u00e9finies des ressources\u00a0! -error.evaluation.resource.climatic.years.missing=Les donn\u00e9es climatiques d\u00e9finies dans les ressources manquent pour les ann\u00e9es {0}\u00a0! -error.evaluation.resource.cropdevelopmentyears.null=La propri\u00e9t\u00e9 ResourceManager.cropDevelopmentYears ne doit pas \u00eatre nulle\u00a0! -error.evaluation.resource.pheno=Erreur pour les donn\u00e9es ph\u00e9nologiques d\u00e9finies dans les ressources\u00a0! -error.evaluation.resource.pheno.empty=Aucune donn\u00e9e ph\u00e9nologique d\u00e9finie dans les ressources\u00a0! -error.evaluation.resource.pheno.years=Erreur pour les ann\u00e9es dans les donn\u00e9es ph\u00e9nologiques des ressources\u00a0! -error.evaluation.resource.pheno.years.empty=Aucune ann\u00e9e dans les donn\u00e9es ph\u00e9nologiques des ressources\u00a0! -error.evaluation.resource.pheno.years.missing=Les donn\u00e9es ph\u00e9nologiques d\u00e9finies dans les ressources manquent pour les ann\u00e9es {0}\u00a0! +error.evaluation.resource=Erreur pour les ressources\u00a0! error.evaluation.resource.soil=Erreur pour l donn\u00e9es de sol\u00a0! error.evaluation.resource.soil.size.wrong=Le nombre de donn\u00e9es de sol ne correspond pas \u00e0 des ann\u00e9es enti\u00e8res\u00a0! -error.evaluation.resource.variables=Erreur pour la propri\u00e9t\u00e9 ResourceManager.variables\u00a0! error.evaluation.resource.variables.empty=La propri\u00e9t\u00e9 ResourceManager.variables ne doit pas \u00eatre vide\u00a0! +error.evaluation.resource.variables=Erreur pour la propri\u00e9t\u00e9 ResourceManager.variables\u00a0! error.evaluation.resource.variables.missing=La propri\u00e9t\u00e9 ResourceManager.variables ne doit pas \u00eatre nulle\u00a0! +error.resources.climate.empty=Aucune donn\u00e9e climatique d\u00e9finie dans les ressources\u00a0! +error.resources.climate.empty.for.phase=Aucune donn\u00e9e climatique pour la phase {0}-{1} (de {2} \u00e0 {3}) en {4}. Donn\u00e9es disponibles entre {5} et {6}. +error.resources.climate.size.wrong=Le nombre de donn\u00e9es climatiques ne correspond pas \u00e0 des ann\u00e9es enti\u00e8res\u00a0! +error.resources.climate.years.empty=Aucune ann\u00e9e dans les donn\u00e9es climatiques d\u00e9finies des ressources\u00a0! +error.resources.climate.years.empty=Erreur pour les ann\u00e9es dans les donn\u00e9es climatiques d\u00e9finies des ressources\u00a0! +error.resources.climate.years.missing=Les donn\u00e9es climatiques d\u00e9finies dans les ressources manquent pour les ann\u00e9es {0}\u00a0! +error.resources.cropdevelopmentyears.null=La propri\u00e9t\u00e9 ResourceManager.cropDevelopmentYears ne doit pas \u00eatre nulle\u00a0! +error.resources.pheno.empty=Aucune donn\u00e9e ph\u00e9nologique d\u00e9finie dans les ressources\u00a0! +error.resources.pheno=Erreur pour les donn\u00e9es ph\u00e9nologiques d\u00e9finies dans les ressources\u00a0! +error.resources.pheno.years.empty=Aucune ann\u00e9e dans les donn\u00e9es ph\u00e9nologiques des ressources\u00a0! +error.resources.pheno.years=Erreur pour les ann\u00e9es dans les donn\u00e9es ph\u00e9nologiques des ressources\u00a0! +error.resources.pheno.years.missing=Les donn\u00e9es ph\u00e9nologiques d\u00e9finies dans les ressources manquent pour les ann\u00e9es {0}\u00a0! error.rh.outofrange={0}\u00a0: ligne {1}\u00a0: l\u2019humidit\u00e9 relative (%) doit \u00eatre comprise dans l\u2019intervalle 0-100. error.title=Erreur error.year.null={0}\u00a0: ligne {1}\u00a0: l\u2019ann\u00e9e est obligatoire. @@ -88,14 +109,6 @@ normalization.MultiLinear=Affine par morceaux normalization.Normal=Normale normalization.Sigmoid=Sigmo\u00efde -JEXLFormula.error.execution=Erreur lors de l\u2019ex\u00e9cution de l\u2019expression \u00ab {0} \u00bb. -JEXLFormula.error.expression.null=L\u2019expression ne peut \u00eatre nulle. -JEXLFormula.error.expression.empty=L\u2019expression ne peut \u00eatre vide. -JEXLFormula.error.expression.parenthesis=Expression non valide \u00ab {0} \u00bb : des parenth\u00e8ses manquent. -JEXLFormula.error.expression.parsing=Expression non valide \u00ab {0} \u00bb : erreur d\u2019analyse. -JEXLFormula.error.variable.undefined=Expression non valide \u00ab {0} \u00bb : la variable \u00ab {1} \u00bb n\u2019est pas d\u00e9finie. -JEXLFormula.error.function.unknown=Expression non valide \u00ab {0} \u00bb : la fonction \u00ab {1} \u00bb est inconnue ou ambig\u00fce. Si la fonction existe, v\u00e9rifiez les arguments. - EvaluationType.WITH_AGGREGATION.name=avec agr\u00e9gation EvaluationType.WITHOUT_AGGREGATION.name=sans agr\u00e9gation diff --git a/src/test/java/fr/inrae/agroclim/indicators/exception/ErrorMessageTest.java b/src/test/java/fr/inrae/agroclim/indicators/exception/ErrorMessageTest.java index 91135245..9d8cbcaa 100644 --- a/src/test/java/fr/inrae/agroclim/indicators/exception/ErrorMessageTest.java +++ b/src/test/java/fr/inrae/agroclim/indicators/exception/ErrorMessageTest.java @@ -52,7 +52,17 @@ public class ErrorMessageTest { @Override public ErrorCategory getCategory() { - return () -> "TEST00"; + return new ErrorCategory() { + @Override + public String getCode() { + return "TEST00"; + } + + @Override + public String getName() { + return "CATEGORY"; + } + }; } @Override diff --git a/src/test/java/fr/inrae/agroclim/indicators/exception/ErrorTypeTest.java b/src/test/java/fr/inrae/agroclim/indicators/exception/ErrorTypeTest.java index 00cda328..863d0896 100644 --- a/src/test/java/fr/inrae/agroclim/indicators/exception/ErrorTypeTest.java +++ b/src/test/java/fr/inrae/agroclim/indicators/exception/ErrorTypeTest.java @@ -2,6 +2,7 @@ package fr.inrae.agroclim.indicators.exception; import fr.inrae.agroclim.indicators.exception.type.ComputationErrorType; import fr.inrae.agroclim.indicators.exception.type.ResourceErrorType; +import fr.inrae.agroclim.indicators.exception.type.XmlErrorType; import static org.junit.Assert.assertTrue; import java.util.ArrayList; @@ -39,7 +40,7 @@ public class ErrorTypeTest { */ @Parameterized.Parameters public static List<Class<? extends Enum<?>>> data() { - return List.of(ComputationErrorType.class, ResourceErrorType.class); + return List.of(ComputationErrorType.class, ResourceErrorType.class, XmlErrorType.class); } /** diff --git a/src/test/java/fr/inrae/agroclim/indicators/model/EvaluationSettingsTest.java b/src/test/java/fr/inrae/agroclim/indicators/model/EvaluationSettingsTest.java index 06872d5d..d5849da6 100644 --- a/src/test/java/fr/inrae/agroclim/indicators/model/EvaluationSettingsTest.java +++ b/src/test/java/fr/inrae/agroclim/indicators/model/EvaluationSettingsTest.java @@ -16,6 +16,7 @@ */ package fr.inrae.agroclim.indicators.model; +import fr.inrae.agroclim.indicators.exception.IndicatorsException; import static org.junit.Assert.assertTrue; import org.junit.Test; @@ -30,7 +31,7 @@ import org.junit.Test; public final class EvaluationSettingsTest { @Test - public void initializeKnowledge() { + public void initializeKnowledge() throws IndicatorsException { EvaluationSettings settings = new EvaluationSettings(); settings.initializeKnowledge(); assertTrue("Knowledge should not be null!", diff --git a/src/test/java/fr/inrae/agroclim/indicators/model/EvaluationWithoutAggregationTest.java b/src/test/java/fr/inrae/agroclim/indicators/model/EvaluationWithoutAggregationTest.java index e9a8794d..6bc18824 100644 --- a/src/test/java/fr/inrae/agroclim/indicators/model/EvaluationWithoutAggregationTest.java +++ b/src/test/java/fr/inrae/agroclim/indicators/model/EvaluationWithoutAggregationTest.java @@ -19,7 +19,6 @@ package fr.inrae.agroclim.indicators.model; import fr.inrae.agroclim.indicators.exception.IndicatorsException; -import fr.inrae.agroclim.indicators.exception.TechnicalException; import fr.inrae.agroclim.indicators.model.data.DataTestHelper; import fr.inrae.agroclim.indicators.model.indicator.CompositeIndicator; import fr.inrae.agroclim.indicators.model.indicator.Indicator; @@ -98,12 +97,11 @@ public class EvaluationWithoutAggregationTest extends DataTestHelper { } /** * Test save() a file. - * @throws fr.inrae.agroclim.indicators.exception.TechnicalException while - * serializing or loading + * @throws IndicatorsException while serializing or loading * @throws java.io.IOException while creating tmp file or writing */ @Test(expected = Test.None.class) - public void save() throws TechnicalException, IOException { + public void save() throws IndicatorsException, IOException { ByteArrayOutputStream baos = new ByteArrayOutputStream(); XMLUtil.serialize(evaluation.getSettings(), baos, EvaluationSettings.CLASSES_FOR_JAXB); diff --git a/src/test/java/fr/inrae/agroclim/indicators/model/KnowledgeDailyTest.java b/src/test/java/fr/inrae/agroclim/indicators/model/KnowledgeDailyTest.java index 1a623d73..7ccdb768 100644 --- a/src/test/java/fr/inrae/agroclim/indicators/model/KnowledgeDailyTest.java +++ b/src/test/java/fr/inrae/agroclim/indicators/model/KnowledgeDailyTest.java @@ -16,10 +16,12 @@ */ package fr.inrae.agroclim.indicators.model; +import fr.inrae.agroclim.indicators.exception.IndicatorsException; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; import java.util.Arrays; import java.util.HashMap; @@ -32,7 +34,6 @@ import java.util.stream.Collectors; import org.junit.BeforeClass; import org.junit.Test; -import fr.inrae.agroclim.indicators.exception.TechnicalException; import fr.inrae.agroclim.indicators.model.data.Variable; import fr.inrae.agroclim.indicators.model.indicator.CompositeIndicator; import fr.inrae.agroclim.indicators.model.indicator.Indicator; @@ -57,8 +58,8 @@ public final class KnowledgeDailyTest { public static void loadXml() { try { knowledge = Knowledge.load(TimeScale.DAILY); - } catch (final TechnicalException ex) { - assertTrue("Loading XML file from Knowledge.load() should work!", false); + } catch (final IndicatorsException ex) { + fail("Loading XML file from Knowledge.load() should work!"); } } diff --git a/src/test/java/fr/inrae/agroclim/indicators/model/KnowledgeHourlyTest.java b/src/test/java/fr/inrae/agroclim/indicators/model/KnowledgeHourlyTest.java index 101f19be..e4e0935e 100644 --- a/src/test/java/fr/inrae/agroclim/indicators/model/KnowledgeHourlyTest.java +++ b/src/test/java/fr/inrae/agroclim/indicators/model/KnowledgeHourlyTest.java @@ -18,7 +18,7 @@ */ package fr.inrae.agroclim.indicators.model; -import fr.inrae.agroclim.indicators.exception.TechnicalException; +import fr.inrae.agroclim.indicators.exception.IndicatorsException; import fr.inrae.agroclim.indicators.model.criteria.Criteria; import fr.inrae.agroclim.indicators.model.criteria.FormulaCriteria; import fr.inrae.agroclim.indicators.model.indicator.CompositeIndicator; @@ -51,7 +51,7 @@ public class KnowledgeHourlyTest { public static void loadXml() { try { knowledge = Knowledge.load(TimeScale.HOURLY); - } catch (final TechnicalException ex) { + } catch (final IndicatorsException ex) { assertTrue("Loading XML file from Knowledge.load() should work!", false); } } diff --git a/src/test/java/fr/inrae/agroclim/indicators/model/KnowledgeTest.java b/src/test/java/fr/inrae/agroclim/indicators/model/KnowledgeTest.java index 3b44ce15..651393b6 100644 --- a/src/test/java/fr/inrae/agroclim/indicators/model/KnowledgeTest.java +++ b/src/test/java/fr/inrae/agroclim/indicators/model/KnowledgeTest.java @@ -16,10 +16,12 @@ */ package fr.inrae.agroclim.indicators.model; +import fr.inrae.agroclim.indicators.exception.IndicatorsException; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; import java.util.ArrayList; import java.util.Arrays; @@ -33,13 +35,13 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; -import fr.inrae.agroclim.indicators.exception.TechnicalException; import fr.inrae.agroclim.indicators.model.data.Variable; import fr.inrae.agroclim.indicators.model.indicator.CompositeIndicator; import fr.inrae.agroclim.indicators.model.indicator.Indicator; import fr.inrae.agroclim.indicators.model.indicator.IndicatorCategory; import fr.inrae.agroclim.indicators.model.indicator.NumberOfWaves; import fr.inrae.agroclim.indicators.model.indicator.Quotient; +import java.util.Objects; /** * Test the class vs the XML file. @@ -71,9 +73,8 @@ public final class KnowledgeTest { public KnowledgeTest(final TimeScale timeScale) { try { knowledge = Knowledge.load(timeScale); - } catch (final TechnicalException ex) { - assertTrue("Loading XML file from Knowledge.load() should work!", - false); + } catch (final IndicatorsException ex) { + fail("Loading XML file from Knowledge.load() should work!"); } } @@ -347,15 +348,14 @@ public final class KnowledgeTest { @Test public void noNullVariables() { getSimpleIndicators().forEach((ind) -> { - System.out.println("=> " + ind); assertNotNull(ind); final String id = ind.getId(); final Set<Variable> vars = ind.getVariables(); assertNotNull(id + ".variables must not be a null set.", vars); - assertTrue(id + ".variables must contain at least one variable.", - !vars.isEmpty()); - assertTrue(id + ".variables must not contains null.", - !vars.contains(null)); + assertTrue(id + ".variables must contain at least one variable.", !vars.isEmpty()); + // with unmodifiable set, contains(null) throws NullPointerException + final boolean contains = vars.stream().anyMatch(Objects::isNull); + assertFalse(id + ".variables must not contains null. variables=" + vars, contains); }); } diff --git a/src/test/java/fr/inrae/agroclim/indicators/model/RaidayMeantTest.java b/src/test/java/fr/inrae/agroclim/indicators/model/RaidayMeantTest.java index ffacfcdc..1c71ef25 100644 --- a/src/test/java/fr/inrae/agroclim/indicators/model/RaidayMeantTest.java +++ b/src/test/java/fr/inrae/agroclim/indicators/model/RaidayMeantTest.java @@ -37,7 +37,6 @@ import org.junit.Before; import org.junit.Test; import fr.inrae.agroclim.indicators.exception.IndicatorsException; -import fr.inrae.agroclim.indicators.exception.TechnicalException; import fr.inrae.agroclim.indicators.model.criteria.RelationalOperator; import fr.inrae.agroclim.indicators.model.criteria.SimpleCriteria; import fr.inrae.agroclim.indicators.model.data.DataTestHelper; @@ -180,7 +179,7 @@ public class RaidayMeantTest extends DataTestHelper { settings = (EvaluationSettings) XMLUtil.load(xmlFile, EvaluationSettings.CLASSES_FOR_JAXB); settings.setFilePath(xmlFile.getAbsolutePath()); - } catch (final TechnicalException ex) { + } catch (final IndicatorsException ex) { LOGGER.error(ex.getLocalizedMessage()); return; } diff --git a/src/test/java/fr/inrae/agroclim/indicators/model/StageDeltaEvaluationTest.java b/src/test/java/fr/inrae/agroclim/indicators/model/StageDeltaEvaluationTest.java index 38b9d376..8e5b6573 100644 --- a/src/test/java/fr/inrae/agroclim/indicators/model/StageDeltaEvaluationTest.java +++ b/src/test/java/fr/inrae/agroclim/indicators/model/StageDeltaEvaluationTest.java @@ -28,7 +28,6 @@ import org.junit.Before; import org.junit.Test; import fr.inrae.agroclim.indicators.exception.IndicatorsException; -import fr.inrae.agroclim.indicators.exception.TechnicalException; import fr.inrae.agroclim.indicators.model.data.DataTestHelper; import fr.inrae.agroclim.indicators.xml.XMLUtil; import lombok.extern.log4j.Log4j2; @@ -56,7 +55,7 @@ public class StageDeltaEvaluationTest extends DataTestHelper { EvaluationSettings.CLASSES_FOR_JAXB); settings.initializeKnowledge(); settings.setFilePath(xmlFile.getAbsolutePath()); - } catch (final TechnicalException ex) { + } catch (final IndicatorsException ex) { LOGGER.error(ex.getLocalizedMessage()); return; } diff --git a/src/test/java/fr/inrae/agroclim/indicators/model/criteria/FormulaCriteriaTest.java b/src/test/java/fr/inrae/agroclim/indicators/model/criteria/FormulaCriteriaTest.java index 63820714..deb63d0b 100644 --- a/src/test/java/fr/inrae/agroclim/indicators/model/criteria/FormulaCriteriaTest.java +++ b/src/test/java/fr/inrae/agroclim/indicators/model/criteria/FormulaCriteriaTest.java @@ -33,7 +33,6 @@ import java.util.Set; import org.junit.Test; -import fr.inrae.agroclim.indicators.exception.TechnicalException; import fr.inrae.agroclim.indicators.model.EvaluationSettings; import fr.inrae.agroclim.indicators.model.ExpressionParameter; import fr.inrae.agroclim.indicators.model.data.Variable; @@ -81,7 +80,7 @@ public class FormulaCriteriaTest { } @Test - public void formulaWithParameter() throws IndicatorsException, TechnicalException { + public void formulaWithParameter() throws IndicatorsException { final FormulaCriteria crit = new FormulaCriteria(); crit.setExpression("formulaCriteria:between(TMEAN, min, max)"); final List<ExpressionParameter> expressionParameters = new ArrayList<>(); diff --git a/src/test/java/fr/inrae/agroclim/indicators/model/criteria/SimpleCriteriaTest.java b/src/test/java/fr/inrae/agroclim/indicators/model/criteria/SimpleCriteriaTest.java index a74af17e..774fefe1 100644 --- a/src/test/java/fr/inrae/agroclim/indicators/model/criteria/SimpleCriteriaTest.java +++ b/src/test/java/fr/inrae/agroclim/indicators/model/criteria/SimpleCriteriaTest.java @@ -14,7 +14,6 @@ import java.nio.charset.StandardCharsets; import org.junit.Test; -import fr.inrae.agroclim.indicators.exception.TechnicalException; import fr.inrae.agroclim.indicators.model.data.Variable; import fr.inrae.agroclim.indicators.model.data.climate.ClimaticDailyData; import fr.inrae.agroclim.indicators.xml.XMLUtil; @@ -87,7 +86,7 @@ public class SimpleCriteriaTest { } @Test(expected = Test.None.class) - public void serializeInferiorToThreshold() throws TechnicalException, UnsupportedEncodingException { + public void serializeInferiorToThreshold() throws IndicatorsException, UnsupportedEncodingException { final Class<?>[] classes = new Class<?>[]{ Criteria.class, SimpleCriteria.class }; final String expected = """ <?xml version="1.0" encoding="UTF-8" standalone="yes"?> @@ -112,7 +111,7 @@ public class SimpleCriteriaTest { } @Test(expected = Test.None.class) - public void unserializeGT() throws IndicatorsException, TechnicalException { + public void unserializeGT() throws IndicatorsException { final Class<?>[] classes = new Class<?>[]{ Criteria.class, SimpleCriteria.class }; final String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>" + "<criteria xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:type=\"simpleCriteria\">" @@ -132,7 +131,7 @@ public class SimpleCriteriaTest { } @Test(expected = Test.None.class) - public void unserializeInferiorToThreshold() throws IndicatorsException, TechnicalException { + public void unserializeInferiorToThreshold() throws IndicatorsException { final Class<?>[] classes = new Class<?>[]{ Criteria.class, SimpleCriteria.class }; final String xml = """ <?xml version="1.0" encoding="UTF-8" ?><criteria xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="simpleCriteria"> <variable>th</variable> diff --git a/src/test/java/fr/inrae/agroclim/indicators/model/data/DataTestHelper.java b/src/test/java/fr/inrae/agroclim/indicators/model/data/DataTestHelper.java index ea7c4864..f2394894 100644 --- a/src/test/java/fr/inrae/agroclim/indicators/model/data/DataTestHelper.java +++ b/src/test/java/fr/inrae/agroclim/indicators/model/data/DataTestHelper.java @@ -16,6 +16,7 @@ */ package fr.inrae.agroclim.indicators.model.data; +import fr.inrae.agroclim.indicators.exception.IndicatorsException; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; @@ -28,7 +29,6 @@ import java.util.Map; import java.util.Properties; import java.util.stream.Collectors; -import fr.inrae.agroclim.indicators.exception.TechnicalException; import fr.inrae.agroclim.indicators.model.Evaluation; import fr.inrae.agroclim.indicators.model.EvaluationSettings; import fr.inrae.agroclim.indicators.model.data.climate.ClimateFileLoader; @@ -269,7 +269,7 @@ public abstract class DataTestHelper { settings = (EvaluationSettings) XMLUtil.load(file, EvaluationSettings.CLASSES_FOR_JAXB); settings.initializeKnowledge(); settings.setFilePath(file.getAbsolutePath()); - } catch (final TechnicalException ex) { + } catch (final IndicatorsException ex) { LOGGER.error(ex.getLocalizedMessage()); return null; } diff --git a/src/test/java/fr/inrae/agroclim/indicators/model/data/ResourceManagerTest.java b/src/test/java/fr/inrae/agroclim/indicators/model/data/ResourceManagerTest.java index d69f5cfe..fea30030 100644 --- a/src/test/java/fr/inrae/agroclim/indicators/model/data/ResourceManagerTest.java +++ b/src/test/java/fr/inrae/agroclim/indicators/model/data/ResourceManagerTest.java @@ -151,7 +151,7 @@ public final class ResourceManagerTest extends DataTestHelper { final Map<ResourceErrorType, ErrorMessage> errors = mgr.getConsitencyErrors(); assertNotNull(errors); final Set<ResourceErrorType> expectedErrors = new HashSet<>(); - expectedErrors.add(ResourceErrorType.CLIMATIC_YEARS); + expectedErrors.add(ResourceErrorType.CLIMATE_YEARS); final String subject = "ResourceManager with only climatic data in 2015 " + "must have errors on climatic resources"; assertEquals(subject, expectedErrors, errors.keySet()); diff --git a/src/test/java/fr/inrae/agroclim/indicators/model/data/climate/ClimateTest.java b/src/test/java/fr/inrae/agroclim/indicators/model/data/climate/ClimateTest.java index f9d1d7c9..f5b291a9 100644 --- a/src/test/java/fr/inrae/agroclim/indicators/model/data/climate/ClimateTest.java +++ b/src/test/java/fr/inrae/agroclim/indicators/model/data/climate/ClimateTest.java @@ -16,6 +16,7 @@ */ package fr.inrae.agroclim.indicators.model.data.climate; +import fr.inrae.agroclim.indicators.exception.IndicatorsException; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; @@ -26,7 +27,6 @@ import java.util.Map; import org.junit.Test; -import fr.inrae.agroclim.indicators.exception.TechnicalException; import fr.inrae.agroclim.indicators.model.EvaluationSettings; import fr.inrae.agroclim.indicators.model.data.DataTestHelper; @@ -62,8 +62,8 @@ public final class ClimateTest extends DataTestHelper { assertNotNull("Loaded ClimaticDailyData list must not be null", data); assertFalse("Loaded ClimaticDailyData list must not be empty", data.isEmpty()); - } catch (final TechnicalException ex) { - error = ex.getMessage() + " " + ex.getRootException().getMessage(); + } catch (final IndicatorsException ex) { + error = ex.getMessage() + " " + ex.getCause().getMessage(); } assertNull(error, error); } diff --git a/src/test/java/fr/inrae/agroclim/indicators/model/data/phenology/PhenologyLoaderTest.java b/src/test/java/fr/inrae/agroclim/indicators/model/data/phenology/PhenologyLoaderTest.java index 949a930a..ee655a14 100644 --- a/src/test/java/fr/inrae/agroclim/indicators/model/data/phenology/PhenologyLoaderTest.java +++ b/src/test/java/fr/inrae/agroclim/indicators/model/data/phenology/PhenologyLoaderTest.java @@ -16,6 +16,7 @@ */ package fr.inrae.agroclim.indicators.model.data.phenology; +import fr.inrae.agroclim.indicators.exception.IndicatorsException; import static org.junit.Assert.assertTrue; import java.io.File; @@ -23,7 +24,6 @@ import java.util.List; import org.junit.Test; -import fr.inrae.agroclim.indicators.exception.TechnicalException; import fr.inrae.agroclim.indicators.model.EvaluationSettings; import fr.inrae.agroclim.indicators.model.data.DataTestHelper; import fr.inrae.agroclim.indicators.xml.XMLUtil; @@ -59,8 +59,8 @@ public final class PhenologyLoaderTest extends DataTestHelper { List<AnnualStageData> data = e.getPhenologyLoader().load(); assertTrue("loaded data must not be null", data != null); assertTrue("loaded data must not be empty", !data.isEmpty()); - } catch (final TechnicalException ex) { - error = ex.getMessage() + " " + ex.getRootException().getMessage(); + } catch (final IndicatorsException ex) { + error = ex.getMessage() + " " + ex.getCause().getMessage(); } assertTrue(error, error == null); } diff --git a/src/test/java/fr/inrae/agroclim/indicators/model/data/soil/SoilCalculatorTest.java b/src/test/java/fr/inrae/agroclim/indicators/model/data/soil/SoilCalculatorTest.java index 5f87c24c..47e88c4a 100644 --- a/src/test/java/fr/inrae/agroclim/indicators/model/data/soil/SoilCalculatorTest.java +++ b/src/test/java/fr/inrae/agroclim/indicators/model/data/soil/SoilCalculatorTest.java @@ -17,7 +17,6 @@ package fr.inrae.agroclim.indicators.model.data.soil; import fr.inrae.agroclim.indicators.exception.ErrorMessage; -import fr.inrae.agroclim.indicators.exception.TechnicalException; import fr.inrae.agroclim.indicators.exception.type.ResourceErrorType; import fr.inrae.agroclim.indicators.model.Evaluation; import fr.inrae.agroclim.indicators.model.EvaluationSettings; @@ -349,11 +348,10 @@ public final class SoilCalculatorTest extends DataTestHelper { /** * Test integration into {@link Evaluation}. * - * @throws TechnicalException if knowledge does not load. * @throws IOException while loading phenology properties */ @Test - public void loadInEvaluation() throws TechnicalException, IOException { + public void loadInEvaluation() throws IOException { final String baseName = "pheno_curve_grapevine_sw_4_stages-chardonnay"; final Properties ini = getPhenologyProperties(baseName); // 1. load Evaluation diff --git a/src/test/java/fr/inrae/agroclim/indicators/model/indicator/AverageTest.java b/src/test/java/fr/inrae/agroclim/indicators/model/indicator/AverageTest.java index 3014fe06..7433ba01 100644 --- a/src/test/java/fr/inrae/agroclim/indicators/model/indicator/AverageTest.java +++ b/src/test/java/fr/inrae/agroclim/indicators/model/indicator/AverageTest.java @@ -33,7 +33,6 @@ import java.nio.file.Path; import org.junit.Test; import fr.inrae.agroclim.indicators.exception.IndicatorsException; -import fr.inrae.agroclim.indicators.exception.TechnicalException; import fr.inrae.agroclim.indicators.model.Knowledge; import fr.inrae.agroclim.indicators.model.TimeScale; import fr.inrae.agroclim.indicators.model.criteria.NoCriteria; @@ -94,7 +93,7 @@ public class AverageTest extends DataTestHelper { } @Test - public void mint() throws TechnicalException, IndicatorsException, CloneNotSupportedException { + public void mint() throws IndicatorsException, CloneNotSupportedException { final Knowledge knowledge = Knowledge.load(TimeScale.DAILY); final String indicatorId = "mint"; final IndicatorCategory expectedCat = IndicatorCategory.INDICATORS; diff --git a/src/test/java/fr/inrae/agroclim/indicators/model/indicator/DiffOfSumTest.java b/src/test/java/fr/inrae/agroclim/indicators/model/indicator/DiffOfSumTest.java index 92c0200a..8291e26f 100644 --- a/src/test/java/fr/inrae/agroclim/indicators/model/indicator/DiffOfSumTest.java +++ b/src/test/java/fr/inrae/agroclim/indicators/model/indicator/DiffOfSumTest.java @@ -6,7 +6,6 @@ import static org.junit.Assert.assertNull; import org.junit.Test; import fr.inrae.agroclim.indicators.exception.IndicatorsException; -import fr.inrae.agroclim.indicators.exception.TechnicalException; import fr.inrae.agroclim.indicators.model.Knowledge; import fr.inrae.agroclim.indicators.model.criteria.SimpleCriteria; import fr.inrae.agroclim.indicators.model.data.DataTestHelper; @@ -72,9 +71,9 @@ public class DiffOfSumTest extends DataTestHelper { /** * sumwd is also defined in knowledge.xml - * @throws TechnicalException while reading the XML + * @throws IndicatorsException while reading the XML */ - public void sumwdFromKnowledge() throws TechnicalException { + public void sumwdFromKnowledge() throws IndicatorsException { final Knowledge knowledge = Knowledge.load(); final SimpleIndicator sumwd = (SimpleIndicator) knowledge.getIndicator("sumwd"); final double expected = climaticData.getData().stream() diff --git a/src/test/java/fr/inrae/agroclim/indicators/model/indicator/ImplementationsTest.java b/src/test/java/fr/inrae/agroclim/indicators/model/indicator/ImplementationsTest.java index 69b9dca8..ebe244b2 100644 --- a/src/test/java/fr/inrae/agroclim/indicators/model/indicator/ImplementationsTest.java +++ b/src/test/java/fr/inrae/agroclim/indicators/model/indicator/ImplementationsTest.java @@ -16,7 +16,7 @@ */ package fr.inrae.agroclim.indicators.model.indicator; -import fr.inrae.agroclim.indicators.exception.TechnicalException; +import fr.inrae.agroclim.indicators.exception.IndicatorsException; import fr.inrae.agroclim.indicators.model.Knowledge; import java.util.ArrayList; import java.util.List; @@ -61,7 +61,7 @@ public class ImplementationsTest { indicators.add(ind); }); } - } catch (final TechnicalException ex) { + } catch (final IndicatorsException ex) { LOGGER.fatal("Loading knowledge should not fail!", ex); } return indicators; diff --git a/src/test/java/fr/inrae/agroclim/indicators/model/indicator/IndicatorTest.java b/src/test/java/fr/inrae/agroclim/indicators/model/indicator/IndicatorTest.java index 78db4252..0ca49112 100644 --- a/src/test/java/fr/inrae/agroclim/indicators/model/indicator/IndicatorTest.java +++ b/src/test/java/fr/inrae/agroclim/indicators/model/indicator/IndicatorTest.java @@ -19,7 +19,7 @@ package fr.inrae.agroclim.indicators.model.indicator; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; import java.util.Map; import java.util.Set; @@ -28,7 +28,6 @@ import org.junit.BeforeClass; import org.junit.Test; import fr.inrae.agroclim.indicators.exception.IndicatorsException; -import fr.inrae.agroclim.indicators.exception.TechnicalException; import fr.inrae.agroclim.indicators.model.EvaluationType; import fr.inrae.agroclim.indicators.model.Knowledge; import fr.inrae.agroclim.indicators.model.Parameter; @@ -119,8 +118,8 @@ public class IndicatorTest extends DataTestHelper { public static void loadXml() { try { knowledge = Knowledge.load(TimeScale.DAILY); - } catch (final TechnicalException ex) { - assertTrue("Loading XML file from Knowledge.load() should work!", false); + } catch (final IndicatorsException ex) { + fail("Loading XML file from Knowledge.load() should work!"); } } @Test diff --git a/src/test/java/fr/inrae/agroclim/indicators/model/indicator/TammFormulaTest.java b/src/test/java/fr/inrae/agroclim/indicators/model/indicator/TammFormulaTest.java index afa28025..846182dd 100644 --- a/src/test/java/fr/inrae/agroclim/indicators/model/indicator/TammFormulaTest.java +++ b/src/test/java/fr/inrae/agroclim/indicators/model/indicator/TammFormulaTest.java @@ -33,8 +33,6 @@ import com.fasterxml.jackson.databind.MappingIterator; import com.fasterxml.jackson.dataformat.csv.CsvMapper; import com.fasterxml.jackson.dataformat.csv.CsvSchema; -import fr.inrae.agroclim.indicators.exception.FunctionalException; -import fr.inrae.agroclim.indicators.exception.TechnicalException; import fr.inrae.agroclim.indicators.model.data.DataTestHelper; import fr.inrae.agroclim.indicators.model.data.climate.ClimaticDailyData; import lombok.Data; @@ -123,7 +121,7 @@ public class TammFormulaTest extends DataTestHelper { } @Test - public void computeDailyValue() throws TechnicalException, FunctionalException { + public void computeDailyValue() { assertNotNull(data); final Tamm indicator = new Tamm(); final double actual = indicator.computeDailyValue(fromTestData(data)); diff --git a/src/test/java/fr/inrae/agroclim/indicators/model/indicator/listener/CompositeIndicatorTest.java b/src/test/java/fr/inrae/agroclim/indicators/model/indicator/listener/CompositeIndicatorTest.java index 7b875fec..06efd484 100644 --- a/src/test/java/fr/inrae/agroclim/indicators/model/indicator/listener/CompositeIndicatorTest.java +++ b/src/test/java/fr/inrae/agroclim/indicators/model/indicator/listener/CompositeIndicatorTest.java @@ -18,7 +18,7 @@ */ package fr.inrae.agroclim.indicators.model.indicator.listener; -import fr.inrae.agroclim.indicators.exception.TechnicalException; +import fr.inrae.agroclim.indicators.exception.IndicatorsException; import fr.inrae.agroclim.indicators.model.Knowledge; import fr.inrae.agroclim.indicators.model.indicator.CompositeIndicator; import fr.inrae.agroclim.indicators.model.indicator.Indicator; @@ -39,7 +39,7 @@ public class CompositeIndicatorTest { private boolean listenerFired = false; @Test - public void addThenRemove() throws TechnicalException { + public void addThenRemove() throws IndicatorsException { CompositeIndicator c = new CompositeIndicator(); c.addFunctionListener((final CompositeIndicator i) -> { listenerFired = true; diff --git a/src/test/java/fr/inrae/agroclim/indicators/model/indicator/listener/PropertyChangeListenerTest.java b/src/test/java/fr/inrae/agroclim/indicators/model/indicator/listener/PropertyChangeListenerTest.java index 22b835bc..90899b49 100644 --- a/src/test/java/fr/inrae/agroclim/indicators/model/indicator/listener/PropertyChangeListenerTest.java +++ b/src/test/java/fr/inrae/agroclim/indicators/model/indicator/listener/PropertyChangeListenerTest.java @@ -18,7 +18,7 @@ */ package fr.inrae.agroclim.indicators.model.indicator.listener; -import fr.inrae.agroclim.indicators.exception.TechnicalException; +import fr.inrae.agroclim.indicators.exception.IndicatorsException; import fr.inrae.agroclim.indicators.model.Knowledge; import fr.inrae.agroclim.indicators.model.criteria.SimpleCriteria; import fr.inrae.agroclim.indicators.model.indicator.Indicator; @@ -51,7 +51,7 @@ public class PropertyChangeListenerTest { private IndicatorEvent.Type eventType; @Test - public void cdaystmin() throws TechnicalException { + public void cdaystmin() throws IndicatorsException { listenerFired = false; Knowledge k = Knowledge.load(); diff --git a/src/test/java/fr/inrae/agroclim/indicators/xml/XMLUtilTest.java b/src/test/java/fr/inrae/agroclim/indicators/xml/XMLUtilTest.java index a8597c49..447f6769 100644 --- a/src/test/java/fr/inrae/agroclim/indicators/xml/XMLUtilTest.java +++ b/src/test/java/fr/inrae/agroclim/indicators/xml/XMLUtilTest.java @@ -16,6 +16,7 @@ */ package fr.inrae.agroclim.indicators.xml; +import fr.inrae.agroclim.indicators.exception.IndicatorsException; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; @@ -34,7 +35,6 @@ import java.util.List; import org.junit.Test; -import fr.inrae.agroclim.indicators.exception.TechnicalException; import fr.inrae.agroclim.indicators.model.Evaluation; import fr.inrae.agroclim.indicators.model.EvaluationSettings; import fr.inrae.agroclim.indicators.model.Knowledge; @@ -67,7 +67,7 @@ public final class XMLUtilTest extends DataTestHelper { try { final File xmlFile = getEvaluationTestFile(); XMLUtil.load(xmlFile, EvaluationSettings.CLASSES_FOR_JAXB); - } catch (final TechnicalException e) { + } catch (final IndicatorsException e) { final StringWriter sw = new StringWriter(); final PrintWriter pw = new PrintWriter(sw); e.printStackTrace(pw); @@ -172,7 +172,7 @@ public final class XMLUtilTest extends DataTestHelper { assertEquals("SoilPhenologyCalculators must be equal", settings.getSoilPhenologyCalculator(), saved.getSoilPhenologyCalculator()); assertEquals(settings, saved); - } catch (final IOException | TechnicalException e) { + } catch (final IOException | IndicatorsException e) { final StringWriter sw = new StringWriter(); final PrintWriter pw = new PrintWriter(sw); e.printStackTrace(pw); @@ -192,9 +192,9 @@ public final class XMLUtilTest extends DataTestHelper { final File xmlFile = new File(System.getProperty("user.dir") + File.separator + "test/xml/does-not-exist.xml"); XMLUtil.load(xmlFile, EvaluationSettings.CLASSES_FOR_JAXB); - } catch (final TechnicalException e) { + } catch (final IndicatorsException e) { exception = true; - if (e.getRootException() instanceof FileNotFoundException) { + if (e.getCause() instanceof FileNotFoundException) { fileNotFoundException = true; } } @@ -212,12 +212,12 @@ public final class XMLUtilTest extends DataTestHelper { final File xmlFile = getFile("knowledge.xml"); assertNotNull("knowledge.xml must be found!", xmlFile); XMLUtil.load(xmlFile, Knowledge.CLASSES_FOR_JAXB); - } catch (final TechnicalException e) { + } catch (final IndicatorsException e) { LOGGER.catching(e); final StringBuilder sb = new StringBuilder(); sb.append(e.getClass().getCanonicalName()).append(": "); sb.append(e.toString()); - Throwable cause = e.getRootException(); + Throwable cause = e.getCause(); while (cause != null) { sb.append(" : ").append(cause.getClass().getCanonicalName()) .append(": ").append(cause.getMessage()); @@ -233,11 +233,10 @@ public final class XMLUtilTest extends DataTestHelper { * Test saving a new evaluation. * * @throws java.io.IOException while creating tmp file. - * @throws fr.inrae.agroclim.indicators.exception.TechnicalException while - * serializing + * @throws IndicatorsException while serializing */ @Test - public void saveEvaluation() throws IOException, TechnicalException { + public void saveEvaluation() throws IOException, IndicatorsException { final String name = "évaluation"; final File clim = getClimate1951File(); final File phen = getPhenoSampleFile(); -- GitLab From 7ae06fc8a490cafb63d680988572cdcf00fc29c8 Mon Sep 17 00:00:00 2001 From: Olivier Maury <Olivier.Maury@inrae.fr> Date: Thu, 21 Dec 2023 14:08:55 +0100 Subject: [PATCH 04/20] Checkstyle --- .../agroclim/indicators/exception/IndicatorsException.java | 3 ++- src/main/java/fr/inrae/agroclim/indicators/xml/XMLUtil.java | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/java/fr/inrae/agroclim/indicators/exception/IndicatorsException.java b/src/main/java/fr/inrae/agroclim/indicators/exception/IndicatorsException.java index 5d143c17..bef29720 100644 --- a/src/main/java/fr/inrae/agroclim/indicators/exception/IndicatorsException.java +++ b/src/main/java/fr/inrae/agroclim/indicators/exception/IndicatorsException.java @@ -39,6 +39,7 @@ public class IndicatorsException extends ErrorMessageException { * unknown.) */ public IndicatorsException(final ErrorType errorType, final Throwable cause, final Serializable... arguments) { - super(new ErrorMessage("fr.inrae.agroclim.indicators.resources.messages", errorType, List.of(arguments)), cause); + super(new ErrorMessage("fr.inrae.agroclim.indicators.resources.messages", errorType, List.of(arguments)), + cause); } } diff --git a/src/main/java/fr/inrae/agroclim/indicators/xml/XMLUtil.java b/src/main/java/fr/inrae/agroclim/indicators/xml/XMLUtil.java index 3ad157fc..8dacd948 100644 --- a/src/main/java/fr/inrae/agroclim/indicators/xml/XMLUtil.java +++ b/src/main/java/fr/inrae/agroclim/indicators/xml/XMLUtil.java @@ -267,7 +267,8 @@ public abstract class XMLUtil { * @throws IndicatorsException * exception from JAXBException */ - public static Object loadResource(final InputStream inputStream, final Class<?>... clazz) throws IndicatorsException { + public static Object loadResource(final InputStream inputStream, final Class<?>... clazz) + throws IndicatorsException { if (inputStream == null) { throw new IndicatorsException(XmlErrorType.FILE_NOT_FOUND, "InputStream should not be null!"); } -- GitLab From 378e0e16653c028db7c8e2c2e4eca75ff7f7c1f8 Mon Sep 17 00:00:00 2001 From: Olivier Maury <Olivier.Maury@inrae.fr> Date: Thu, 21 Dec 2023 15:13:56 +0100 Subject: [PATCH 05/20] Messages --- .gitlab-ci.yml | 10 ++- .../exception/type/CommonErrorType.java | 6 +- .../exception/type/ResourceErrorType.java | 6 +- .../indicators/model/JEXLFormula.java | 14 ---- .../model/indicator/AggregationIndicator.java | 2 + .../indicators/resources/messages.properties | 38 +++++----- .../resources/messages_fr.properties | 71 ++++++++++--------- 7 files changed, 68 insertions(+), 79 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 36caf5f4..474a7029 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -6,9 +6,7 @@ image: registry.forgemia.inra.fr/agroclim/common/docker-projets-java:latest stages: - build - test - - checkstyle - - pmd - - cpd + - code-check - package - deploy @@ -37,17 +35,17 @@ test_job: - target/failsafe-reports/TEST-*.xml checkstyle_job: - stage: checkstyle + stage: code-check script: - mvn checkstyle:checkstyle pmd_job: - stage: pmd + stage: code-check script: - mvn pmd:pmd cpd_job: - stage: cpd + stage: code-check script: - mvn pmd:cpd diff --git a/src/main/java/fr/inrae/agroclim/indicators/exception/type/CommonErrorType.java b/src/main/java/fr/inrae/agroclim/indicators/exception/type/CommonErrorType.java index 67e89b0e..b500fab0 100644 --- a/src/main/java/fr/inrae/agroclim/indicators/exception/type/CommonErrorType.java +++ b/src/main/java/fr/inrae/agroclim/indicators/exception/type/CommonErrorType.java @@ -30,10 +30,8 @@ public interface CommonErrorType extends ErrorType { if (!getShortKey().startsWith(cat)) { sj.add(cat); } - if (getParent() != null) { - if (!getShortKey().startsWith(getParent().getShortKey())) { - sj.add(getParent().getShortKey()); - } + if (getParent() != null && !getShortKey().startsWith(getParent().getShortKey())) { + sj.add(getParent().getShortKey()); } sj.add(getShortKey()); return sj.toString(); diff --git a/src/main/java/fr/inrae/agroclim/indicators/exception/type/ResourceErrorType.java b/src/main/java/fr/inrae/agroclim/indicators/exception/type/ResourceErrorType.java index 09631ddb..6be38b76 100644 --- a/src/main/java/fr/inrae/agroclim/indicators/exception/type/ResourceErrorType.java +++ b/src/main/java/fr/inrae/agroclim/indicators/exception/type/ResourceErrorType.java @@ -79,16 +79,12 @@ public enum ResourceErrorType implements CommonErrorType { * No parameter. */ PHENO_YEARS_EMPTY("211", PHENO_YEARS), - /** - * Resource in general, topic. - */ - RESOURCES("001", null), /** * Setting not set. * * No parameter. */ - RESOURCES_CROPDEVELOPMENT_YEARS("002", RESOURCES), + RESOURCES_CROPDEVELOPMENT_YEARS("001", null), /** * Soil, topic. * diff --git a/src/main/java/fr/inrae/agroclim/indicators/model/JEXLFormula.java b/src/main/java/fr/inrae/agroclim/indicators/model/JEXLFormula.java index 98c5b2be..8085763a 100644 --- a/src/main/java/fr/inrae/agroclim/indicators/model/JEXLFormula.java +++ b/src/main/java/fr/inrae/agroclim/indicators/model/JEXLFormula.java @@ -20,7 +20,6 @@ package fr.inrae.agroclim.indicators.model; import java.util.HashSet; import java.util.List; -import java.util.Locale; import java.util.Map; import java.util.Objects; import java.util.Set; @@ -40,7 +39,6 @@ import fr.inrae.agroclim.indicators.exception.type.ComputationErrorType; import fr.inrae.agroclim.indicators.model.criteria.FormulaCriteria; import fr.inrae.agroclim.indicators.model.data.Variable; import fr.inrae.agroclim.indicators.model.function.aggregation.MathMethod; -import fr.inrae.agroclim.indicators.resources.I18n; import fr.inrae.agroclim.indicators.util.StringUtils; import lombok.Getter; import lombok.Setter; @@ -101,18 +99,6 @@ public class JEXLFormula { .create(); } - /** - * Return error message with inlined arguments. - * - * @param key message key, without prefix - * @param messageArguments arguments for the message. - * @return message with arguments - */ - private String errorMessage(final String key, final Object... messageArguments) { - final I18n res = new I18n("fr.inrae.agroclim.indicators.resources.messages", Locale.getDefault()); - return res.format(ERROR_PREFIX + key, messageArguments); - } - /** * Evaluates the expression with the variables. * diff --git a/src/main/java/fr/inrae/agroclim/indicators/model/indicator/AggregationIndicator.java b/src/main/java/fr/inrae/agroclim/indicators/model/indicator/AggregationIndicator.java index 142912ab..33ad49c7 100644 --- a/src/main/java/fr/inrae/agroclim/indicators/model/indicator/AggregationIndicator.java +++ b/src/main/java/fr/inrae/agroclim/indicators/model/indicator/AggregationIndicator.java @@ -53,6 +53,8 @@ public abstract class AggregationIndicator extends SimpleIndicatorWithCriteria i /** * Override {@link SimpleIndicatorWithCriteria#clone()}. + * @return clone + * @throws CloneNotSupportedException should not occur */ @Override public AggregationIndicator clone() throws CloneNotSupportedException { diff --git a/src/main/resources/fr/inrae/agroclim/indicators/resources/messages.properties b/src/main/resources/fr/inrae/agroclim/indicators/resources/messages.properties index dc7ffc32..72ec24e6 100644 --- a/src/main/resources/fr/inrae/agroclim/indicators/resources/messages.properties +++ b/src/main/resources/fr/inrae/agroclim/indicators/resources/messages.properties @@ -31,23 +31,23 @@ error.computation.formula.expression.parenthesis=Invalid expression "{0}": missi error.computation.formula.expression.parsing=Invalid expression "{0}": parsing error. error.computation.formula.function.unknown=Invalid expression "{0}": the function "{1}" is unknown or ambiguous. If the function exists check arguments. error.computation.formula.variable.undefined=Invalid expression "{0}": the variable "{1}" is not defined. -error.computation.input= -error.computation.input.composite.computation= -error.computation.input.data.null= -error.computation.input.quotient.dividend.exception= -error.computation.input.quotient.divisor.exception= -error.computation.input.quotient.divisor.zero= -error.computation.input.variable.value.null= -error.computation.wrong.definition.criteria.null= -error.computation.wrong.definition.quotient.dividend.null= -error.computation.wrong.definition.quotient.divisor.null= -error.computation.wrong.definition.threshold.null= -error.computation.wrong.definition.variable.name.null= +error.computation.input=Indicator computation failed due to an invalid input. +error.computation.input.composite.computation=An indicator in the CompositeIndicator "{0}" failed to compute. +error.computation.input.data.null=Daily data must not be null. +error.computation.input.quotient.dividend.exception=Computation of the dividend indicator "{0}" in Quotient failed. +error.computation.input.quotient.divisor.exception=Computation of the divisor indicator "{0}" in Quotient failed. +error.computation.input.quotient.divisor.zero=The result of the divisor indicator "{0}" is zero. +error.computation.input.variable.value.null=The value for the variable "{0}" must not be null at "{1}". +error.computation.wrong.definition.criteria.null=The "criteria" property must not be null. +error.computation.wrong.definition.quotient.dividend.null=Dividend indicator must not be null. +error.computation.wrong.definition.quotient.divisor.null=Divisor indicator must not be null. +error.computation.wrong.definition.threshold.null=The threshold must not be null. +error.computation.wrong.definition.variable.name.null=The variable name must not be null. error.day.duplicate={0}: line {1}: this is the same date as previous line "{2}". error.day.missing={0}: line {1}: a day is missing before "{2}". -error.resources.climate= -error.resources= -error.resources.cropdevelopment.years= +error.resources.climate=Error for climate data +error.resources=Error for resources +error.resources.cropdevelopment.years=The number of development years for the crop is not set. error.resources.soil=Error for soil data! error.resources.soil.size.wrong=The number of soil data does not match whole years! error.resources.variables=Error for the property ResourceManager.variables! @@ -65,9 +65,9 @@ error.resources.pheno=Error for phenological data set in resources! error.resources.pheno.years.empty=No year in phenological data set in resources! error.resources.pheno.years=Error for years in phenological data set in resources! error.resources.pheno.years.missing=Phenological data set in resources miss for years {0}! -error.xml.file.not.found= -error.xml.unable.to.load= -error.xml.unable.to.serialize= +error.xml.file.not.found=The XML file "{0}" was not found. +error.xml.unable.to.load=XML loading failed. +error.xml.unable.to.serialize=XML serializing failed. error.day.null={0}: line {1}: day is required. error.day.succession={0}: line {1}: the day "{2}" is ealier than the day of the previous line "{3}". error.date.notread=The start and/or end date could not be read @@ -90,6 +90,8 @@ warning.tmax.inferiorto.tmin={0}: line {1}: minimal temperature must be inferior #eg. CLIMATE: line 0: Climatic variable is missing warning.missing={0}: line {1}: {2} is missing warning.soilcalculator.4stages=Phenological stages are provided on {0} stages, but SoilCalculator needs 4 stages! +warning.soilcalculator.4stages[none]=No phenological stage provided whereas soil water balance needs 4 stages! +warning.soilcalculator.4stages[one]=One phenological stage provided whereas soil water balance needs 4 stages! warning.soilloader.missing=No configuration to compute soil water balance or water reserve which are needed for some indicators. markdown.description.daily=List of available indicators at daily timescale diff --git a/src/main/resources/fr/inrae/agroclim/indicators/resources/messages_fr.properties b/src/main/resources/fr/inrae/agroclim/indicators/resources/messages_fr.properties index 090adcc7..b43f027f 100644 --- a/src/main/resources/fr/inrae/agroclim/indicators/resources/messages_fr.properties +++ b/src/main/resources/fr/inrae/agroclim/indicators/resources/messages_fr.properties @@ -23,46 +23,50 @@ warning.tmax.inferiorto.tmin={0}\u00a0: ligne {1}\u00a0: la temp\u00e9rature min error.climate.dates=Pour l\u2019ann\u00e9e {0}, les dates lues vont du {1} au {2}. error.climate.no.data=Aucune donn\u00e9e n\u2019a \u00e9t\u00e9 r\u00e9cup\u00e9r\u00e9e. error.climate.wrong.headers=Mauvais nombre d\u2019ent\u00eates\u00a0! {0} ent\u00eates sont dans le fichier : {1}, mais {2} ent\u00eates sont d\u00e9finis : {3}. -error.computation.formula=Erreur lors de l\u2019ex\u00e9cution de l\u2019expression \u00ab {0} \u00bb. error.computation.formula.aggregation.null=L\u2019agr\u00e9gation ne peut \u00eatre nulle. +error.computation.formula=Erreur lors de l\u2019ex\u00e9cution de l\u2019expression \u00ab {0} \u00bb. error.computation.formula.expression.blank=L\u2019expression ne peut \u00eatre vide. error.computation.formula.expression.null=L\u2019expression ne peut \u00eatre nulle. error.computation.formula.expression.parenthesis=Expression non valide \u00ab {0} \u00bb : des parenth\u00e8ses manquent. error.computation.formula.expression.parsing=Expression non valide \u00ab {0} \u00bb : erreur d\u2019analyse. error.computation.formula.function.unknown=Expression non valide \u00ab {0} \u00bb : la fonction \u00ab {1} \u00bb est inconnue ou ambig\u00fce. Si la fonction existe, v\u00e9rifiez les arguments. error.computation.formula.variable.undefined=Expression non valide \u00ab {0} \u00bb : la variable \u00ab {1} \u00bb n\u2019est pas d\u00e9finie. - -error.computation.input= -error.computation.input.composite.computation= -error.computation.input.data.null= -error.computation.input.quotient.dividend.exception= -error.computation.input.quotient.divisor.exception= -error.computation.input.quotient.divisor.zero= -error.computation.input.variable.value.null= -error.computation.wrong.definition.criteria.null= -error.computation.wrong.definition.quotient.dividend.null= -error.computation.wrong.definition.quotient.divisor.null= -error.computation.wrong.definition.threshold.null= -error.computation.wrong.definition.variable.name.null= +error.computation.input=Le calcul de l\u2019indicateur a \u00e9chou\u00e9 \u00e0 cause d\u2019une entr\u00e9e invalide. +error.computation.input.composite.computation=Le calcul d\u2019un indicateur composant \u00ab {0} \u00bb a \u00e9chou\u00e9. +error.computation.input.data.null=Les donn\u00e9es journali\u00e8res ne doivent pas \u00eatre nulles. +error.computation.input.quotient.dividend.exception=Le calcul de l\u2019indicateur num\u00e9rateur \u00ab {0} \u00bb dans Quotient a \u00e9chou\u00e9. +error.computation.input.quotient.divisor.exception=Le calcul de l\u2019indicateur d\u00e9nominateur \u00ab {0} \u00bb dans Quotient a \u00e9chou\u00e9. +error.computation.input.quotient.divisor.zero=Le r\u00e9sultat du calcul de l\u2019indicateur d\u00e9nominateur \u00ab {0} \u00bb est z\u00e9ro. +error.computation.input.variable.value.null=La valeur de la variable \u00ab {0} \u00bb ne doit pas \u00eatre nulle le \u00ab {1} \u00bb. +error.computation.wrong.definition.criteria.isnt.nocriteria.simplecriteria=criteria n\u2019est ni NoCriteria ni SimpleCriteria\u00a0! +error.computation.wrong.definition.criteria.null=La propri\u00e9t\u00e9 \u00ab criteria \u00bb ne doit pas \u00eatre nulle. +error.computation.wrong.definition=L\u2019indicateur \u00ab {0} \u00bb n\u2019est pas bien d\u00e9fini : {1}. +error.computation.wrong.definition.quotient.dividend.null=L\u2019indicateur num\u00e9rateur ne doit pas \u00eatre nul. +error.computation.wrong.definition.quotient.divisor.null=L\u2019indicateur d\u00e9nominateur ne doit pas \u00eatre nul. +error.computation.wrong.definition.threshold.null=Le seuil ne doit pas \u00eatre null. +error.computation.wrong.definition.variable.name.null=Le nom de la variable ne doit pas \u00eatre nul. error.evaluation.resource.climatic=Erreur pour les donn\u00e9es climatiques d\u00e9finies dans les ressources\u00a0! error.evaluation.resource=Erreur pour les ressources\u00a0! -error.evaluation.resource.soil=Erreur pour l donn\u00e9es de sol\u00a0! -error.evaluation.resource.soil.size.wrong=Le nombre de donn\u00e9es de sol ne correspond pas \u00e0 des ann\u00e9es enti\u00e8res\u00a0! -error.evaluation.resource.variables.empty=La propri\u00e9t\u00e9 ResourceManager.variables ne doit pas \u00eatre vide\u00a0! -error.evaluation.resource.variables=Erreur pour la propri\u00e9t\u00e9 ResourceManager.variables\u00a0! -error.evaluation.resource.variables.missing=La propri\u00e9t\u00e9 ResourceManager.variables ne doit pas \u00eatre nulle\u00a0! error.resources.climate.empty=Aucune donn\u00e9e climatique d\u00e9finie dans les ressources\u00a0! error.resources.climate.empty.for.phase=Aucune donn\u00e9e climatique pour la phase {0}-{1} (de {2} \u00e0 {3}) en {4}. Donn\u00e9es disponibles entre {5} et {6}. +error.resources.climate=Erreurs pour les donn\u00e9es climatiques error.resources.climate.size.wrong=Le nombre de donn\u00e9es climatiques ne correspond pas \u00e0 des ann\u00e9es enti\u00e8res\u00a0! error.resources.climate.years.empty=Aucune ann\u00e9e dans les donn\u00e9es climatiques d\u00e9finies des ressources\u00a0! -error.resources.climate.years.empty=Erreur pour les ann\u00e9es dans les donn\u00e9es climatiques d\u00e9finies des ressources\u00a0! +error.resources.climate.years=Erreur pour les ann\u00e9es dans les donn\u00e9es climatiques d\u00e9finies des ressources\u00a0! error.resources.climate.years.missing=Les donn\u00e9es climatiques d\u00e9finies dans les ressources manquent pour les ann\u00e9es {0}\u00a0! +error.resources.cropdevelopment.years=Le nombre d\u2019ann\u00e9es de d\u00e9veloppement de la culture n\u2019est pas d\u00e9fini. error.resources.cropdevelopmentyears.null=La propri\u00e9t\u00e9 ResourceManager.cropDevelopmentYears ne doit pas \u00eatre nulle\u00a0! +error.resources=Erreurs pour les ressources error.resources.pheno.empty=Aucune donn\u00e9e ph\u00e9nologique d\u00e9finie dans les ressources\u00a0! error.resources.pheno=Erreur pour les donn\u00e9es ph\u00e9nologiques d\u00e9finies dans les ressources\u00a0! error.resources.pheno.years.empty=Aucune ann\u00e9e dans les donn\u00e9es ph\u00e9nologiques des ressources\u00a0! error.resources.pheno.years=Erreur pour les ann\u00e9es dans les donn\u00e9es ph\u00e9nologiques des ressources\u00a0! error.resources.pheno.years.missing=Les donn\u00e9es ph\u00e9nologiques d\u00e9finies dans les ressources manquent pour les ann\u00e9es {0}\u00a0! +error.resources.soil=Erreurs pour les donn\u00e9es sol +error.resources.soil.size.wrong=Le nombre de donn\u00e9es de sol ne correspond pas \u00e0 des ann\u00e9es enti\u00e8res\u00a0! +error.resources.variables.empty=La propri\u00e9t\u00e9 ResourceManager.variables ne doit pas \u00eatre vide\u00a0! +error.resources.variables=Erreur pour la propri\u00e9t\u00e9 ResourceManager.variables\u00a0! +error.resources.variables.missing=La propri\u00e9t\u00e9 ResourceManager.variables ne doit pas \u00eatre nulle\u00a0! error.rh.outofrange={0}\u00a0: ligne {1}\u00a0: l\u2019humidit\u00e9 relative (%) doit \u00eatre comprise dans l\u2019intervalle 0-100. error.title=Erreur error.year.null={0}\u00a0: ligne {1}\u00a0: l\u2019ann\u00e9e est obligatoire. @@ -71,7 +75,7 @@ error.day.duplicate={0}\u00a0: ligne {1}\u00a0: la date est la m\u00eame dans la error.day.missing={0}\u00a0: ligne {1}\u00a0: un jour manque avant \u00ab\u00a0{2}\u00a0\u00bb. error.day.null={0}\u00a0: ligne {1}\u00a0: le jour est obligatoire. error.day.succession={0}\u00a0: ligne {1}\u00a0: le jour \u00ab\u00a0{2}\u00a0\u00bb est ant\u00e9rieur au jour de la ligne pr\u00e9c\u00e9dente \u00ab\u00a0{3}\u00a0\u00bb. -error.date.notread=La date de d\u00e9but et/ou de fin n'a pas pu \u00eatre lue +error.date.notread=La date de d\u00e9but et/ou de fin n\u2019a pas pu \u00eatre lue error.minimal.stages={0}\u00a0: ligne {1}\u00a0: le fichier ph\u00e9nologique doit contenir au moins deux stades. error.climate.jdbc.query=Erreur lors de l\u2019ex\u00e9cution de la requ\u00eate \u00ab\u00a0{0}\u00a0\u00bb\u00a0! error.endstage.superiorto.startstage={0}\u00a0: ligne {1}\u00a0: le stade actuel ne peut \u00eatre ant\u00e9rieur au stade suivant. @@ -113,25 +117,25 @@ EvaluationType.WITH_AGGREGATION.name=avec agr\u00e9gation EvaluationType.WITHOUT_AGGREGATION.name=sans agr\u00e9gation MathMethod.avg.description = Renvoie la moyenne des valeurs pass\u00e9es en param\u00e8tre de la fonction. -MathMethod.exp.description = Renvoie le nombre Euler e \u00e9lev\u00e9 \u00e0 la puissance d'une valeur double. Cas sp\u00e9ciaux :\n\n\ -Si l'argument est NaN, le r\u00e9sultat est NaN.\n\ -Si l'argument in l'infini positif, le r\u00e9sultat est l'infini positif.\n\ -Si l'argument in l'infini n\u00e9gatif, le r\u00e9sultat est z\u00e9ro positif.\n\ +MathMethod.exp.description = Renvoie le nombre Euler e \u00e9lev\u00e9 \u00e0 la puissance d\u2019une valeur double. Cas sp\u00e9ciaux :\n\n\ +Si l\u2019argument est NaN, le r\u00e9sultat est NaN.\n\ +Si l\u2019argument in l\u2019infini positif, le r\u00e9sultat est l\u2019infini positif.\n\ +Si l\u2019argument in l\u2019infini n\u00e9gatif, le r\u00e9sultat est z\u00e9ro positif.\n\ The computed result must be within 1 ulp of the exact result. Results must be semi-monotonic. MathMethod.log.description=Returns the natural logarithm (base e) of a double value. Special cases:\n\n\ -Si l'argument est NaN ou n\u00e9gatif, le r\u00e9sultat est NaN.\n\ -Si l'argument in l'infini positif, le r\u00e9sultat est l'infini positif.\n\ -Si l'argument est z\u00e9ro (positif ou n\u00e9gatif), le r\u00e9sultat est l'infini n\u00e9gatif.\n\n +Si l\u2019argument est NaN ou n\u00e9gatif, le r\u00e9sultat est NaN.\n\ +Si l\u2019argument in l\u2019infini positif, le r\u00e9sultat est l\u2019infini positif.\n\ +Si l\u2019argument est z\u00e9ro (positif ou n\u00e9gatif), le r\u00e9sultat est l\u2019infini n\u00e9gatif.\n\n The computed result must be within 1 ulp of the exact result. Results must be semi-monotonic. MathMethod.max.description = Renvoie la plus grande des valeurs.\n\n\ -C'est-\u00e0-dire que le r\u00e9sultat est l'argument le plus proche de l'infini positif.\n\ +C\u2019est-\u00e0-dire que le r\u00e9sultat est l\u2019argument le plus proche de l\u2019infini positif.\n\ Si les arguments ont la m\u00eame valeur, le r\u00e9sultat est cette m\u00eame valeur.\n\ -Si l'une des valeurs est NaN, le r\u00e9sultat est NaN.\n\ +Si l\u2019une des valeurs est NaN, le r\u00e9sultat est NaN.\n\ La fonction prend un ou plusieurs arguments en entr\u00e9e. MathMethod.min.description = Retourner la plus petite des valeurs.\n\n\ -C'est-\u00e0-dire que le r\u00e9sultat est la valeur la plus proche de l'infini n\u00e9gatif.\n\ +C\u2019est-\u00e0-dire que le r\u00e9sultat est la valeur la plus proche de l\u2019infini n\u00e9gatif.\n\ Si les arguments ont la m\u00eame valeur, le r\u00e9sultat est cette m\u00eame valeur.\n\ -Si l'une des valeurs est NaN, le r\u00e9sultat est NaN.\n\ +Si l\u2019une des valeurs est NaN, le r\u00e9sultat est NaN.\n\ La fonction prend un ou plusieurs arguments en entr\u00e9e. PhenologicalModelType.curve.name=curvilin\u00e9aire PhenologicalModelType.curve_grapevine.name=curvilin\u00e9aire vigne @@ -152,3 +156,6 @@ Variable.RH.description=Humidit\u00e9 relative [%]. Variable.SOILWATERCONTENT.description=Teneur en eau du sol [% massique]. Variable.WATER_RESERVE.description=R\u00e9serve en eau du sol [mm]. Variable.WIND.description=Vitesse du vent [m/s]. +error.xml.file.not.found=Le fichier XML \u00ab {0} \u00bb n\u2019a pas \u00e9t\u00e9 trouv\u00e9. +error.xml.unable.to.load=Le chargement du fichier XML a \u00e9chou\u00e9. +error.xml.unable.to.serialize=La s\u00e9rialisation du fichier XML a \u00e9chou\u00e9. -- GitLab From f85ba87a8ca5c88b659ece5aa041f84d2827f344 Mon Sep 17 00:00:00 2001 From: Olivier Maury <Olivier.Maury@inrae.fr> Date: Thu, 21 Dec 2023 15:37:53 +0100 Subject: [PATCH 06/20] 1.3.0-SNAPSHOT --- CITATION.cff | 4 ++-- codemeta.json | 2 +- pom.xml | 2 +- publiccode.yml | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/CITATION.cff b/CITATION.cff index fee74dc4..68322cdb 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -13,8 +13,8 @@ keywords: - Java - library - indicators -version: 1.2.5-SNAPSHOT +version: 1.3.0-SNAPSHOT doi: 10.15454/IZUFAP -date-released: 2023-12-19 +date-released: 2023-12-21 license: GPL-3.0 repository-code: https://forgemia.inra.fr/agroclim/Indicators/indicators-java.git diff --git a/codemeta.json b/codemeta.json index a5f97b95..1429d446 100644 --- a/codemeta.json +++ b/codemeta.json @@ -99,5 +99,5 @@ "name": "lombok" } ], - "version": "1.2.5-SNAPSHOT" + "version": "1.3.0-SNAPSHOT" } diff --git a/pom.xml b/pom.xml index d6e135a2..b20bf8e8 100644 --- a/pom.xml +++ b/pom.xml @@ -22,7 +22,7 @@ along with Indicators. If not, see <https://www.gnu.org/licenses/>. <name>Indicators</name> <description>Library of agro- and eco-climatic indicators.</description> <inceptionYear>2018</inceptionYear> - <version>1.2.5-SNAPSHOT</version> + <version>1.3.0-SNAPSHOT</version> <packaging>jar</packaging> <licenses> <license> diff --git a/publiccode.yml b/publiccode.yml index c7537c5b..3cc75557 100644 --- a/publiccode.yml +++ b/publiccode.yml @@ -49,9 +49,9 @@ maintenance: name: "J\xE9r\xE9mie D\xE9c\xF4me" type: internal name: Indicators -releaseDate: 2023-12-19 +releaseDate: 2023-12-21 softwareType: library -softwareVersion: 1.2.5-SNAPSHOT +softwareVersion: 1.3.0-SNAPSHOT url: https://forgemia.inra.fr/agroclim/Indicators/indicators-java.git usedBy: - INRAE AgroClim -- GitLab From c44a9b20fcdd393f1acc9d43248f8923e530826f Mon Sep 17 00:00:00 2001 From: Olivier Maury <Olivier.Maury@inrae.fr> Date: Wed, 3 Jan 2024 14:57:57 +0100 Subject: [PATCH 07/20] PMD --- .../java/fr/inrae/agroclim/indicators/model/JEXLFormula.java | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/main/java/fr/inrae/agroclim/indicators/model/JEXLFormula.java b/src/main/java/fr/inrae/agroclim/indicators/model/JEXLFormula.java index 8085763a..4eb2e1ef 100644 --- a/src/main/java/fr/inrae/agroclim/indicators/model/JEXLFormula.java +++ b/src/main/java/fr/inrae/agroclim/indicators/model/JEXLFormula.java @@ -54,11 +54,6 @@ import org.apache.commons.jexl3.introspection.JexlPermissions; */ public class JEXLFormula { - /** - * I18N key prefix for error messages. - */ - private static final String ERROR_PREFIX = JEXLFormula.class.getSimpleName() + ".error."; - /** * org.apache.commons.jexl3.JexlEngine . */ -- GitLab From dbd53987d5d6e60d3c1d9575ef33693ebc0a362d Mon Sep 17 00:00:00 2001 From: Olivier Maury <Olivier.Maury@inrae.fr> Date: Wed, 3 Jan 2024 16:02:30 +0100 Subject: [PATCH 08/20] .gitlab-ci.yml : `needs` --- .gitlab-ci.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 474a7029..75197667 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -24,6 +24,7 @@ build_job: test_job: stage: test + needs: ["build_job"] script: - echo "Maven test started" - mvn test @@ -36,16 +37,19 @@ test_job: checkstyle_job: stage: code-check + needs: ["build_job"] script: - mvn checkstyle:checkstyle pmd_job: stage: code-check + needs: ["build_job"] script: - mvn pmd:pmd cpd_job: stage: code-check + needs: ["build_job"] script: - mvn pmd:cpd -- GitLab From 62f3500c86ca44890bdd6902fa1893090dc8921a Mon Sep 17 00:00:00 2001 From: Olivier Maury <Olivier.Maury@inrae.fr> Date: Wed, 3 Jan 2024 16:29:24 +0100 Subject: [PATCH 09/20] Factoriser pour tester ErrorType --- .../indicators/util/ErrorTypeUtils.java | 60 +++++++++++++++++++ .../indicators/exception/ErrorTypeTest.java | 38 ++---------- 2 files changed, 65 insertions(+), 33 deletions(-) create mode 100644 src/main/java/fr/inrae/agroclim/indicators/util/ErrorTypeUtils.java diff --git a/src/main/java/fr/inrae/agroclim/indicators/util/ErrorTypeUtils.java b/src/main/java/fr/inrae/agroclim/indicators/util/ErrorTypeUtils.java new file mode 100644 index 00000000..443a9d90 --- /dev/null +++ b/src/main/java/fr/inrae/agroclim/indicators/util/ErrorTypeUtils.java @@ -0,0 +1,60 @@ +package fr.inrae.agroclim.indicators.util; + +import fr.inrae.agroclim.indicators.exception.ErrorType; +import fr.inrae.agroclim.indicators.resources.I18n; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Set; + +/** + * Helper methods to ensure all implementations of {@link ErrorType} are well defined. + * + * @author Olivier Maury + */ +public interface ErrorTypeUtils { + + static Set<String> getDuplicatedCodes(final Class<? extends Enum<?>> clazz) { + final Set<String> duplicates = new HashSet<>(); + final Set<String> codes = new HashSet<>(); + final Enum<?>[] values = clazz.getEnumConstants(); + for (final Enum<?> value : values) { + final ErrorType k = (ErrorType) value; + if (codes.contains(k.getSubCode())) { + duplicates.add(k.getSubCode()); + } + codes.add(k.getSubCode()); + } + return duplicates; + } + + /** + * Get missing translations for the Enum in the bundle for the locales. + * + * @param clazz enum class + * @param bundleName bundle name for the Properties file. + * @param locales locales of translations + * @return missing translations + */ + static Map<Locale, Map<Class<?>, List<String>>> getMissingTranslations(final Class<? extends Enum<?>> clazz, + final String bundleName, final List<Locale> locales) { + final Map<Locale, Map<Class<?>, List<String>>> missing = new HashMap<>(); + for (final Locale locale : locales) { + final I18n i18n = new I18n(bundleName, locale); + final Enum<?>[] values = clazz.getEnumConstants(); + for (final Enum<?> value : values) { + final ErrorType k = (ErrorType) value; + final String tr = i18n.get(k.getI18nKey()); + if (tr.startsWith("!") && tr.endsWith("!")) { + missing.computeIfAbsent(locale, l -> new HashMap<>()); + missing.get(locale).computeIfAbsent(clazz, l -> new ArrayList<>()); + missing.get(locale).get(clazz).add(k.getI18nKey()); + } + } + } + return missing; + } +} diff --git a/src/test/java/fr/inrae/agroclim/indicators/exception/ErrorTypeTest.java b/src/test/java/fr/inrae/agroclim/indicators/exception/ErrorTypeTest.java index 863d0896..dfed45e2 100644 --- a/src/test/java/fr/inrae/agroclim/indicators/exception/ErrorTypeTest.java +++ b/src/test/java/fr/inrae/agroclim/indicators/exception/ErrorTypeTest.java @@ -5,10 +5,6 @@ import fr.inrae.agroclim.indicators.exception.type.ResourceErrorType; import fr.inrae.agroclim.indicators.exception.type.XmlErrorType; import static org.junit.Assert.assertTrue; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.HashSet; import java.util.List; import java.util.Locale; import java.util.Map; @@ -18,15 +14,12 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; -import fr.inrae.agroclim.indicators.resources.I18n; +import fr.inrae.agroclim.indicators.util.ErrorTypeUtils; /** * Ensure all implementations of {@link ErrorType} are well defined. * - * Last changed : $Date: 2023-03-16 17:36:45 +0100 (jeu. 16 mars 2023) $ - * - * @author $Author: omaury $ - * @version $Revision: 644 $ + * @author Olivier Maury */ @RunWith(Parameterized.class) public class ErrorTypeTest { @@ -59,35 +52,14 @@ public class ErrorTypeTest { @Test public void i18n() { - final Map<Locale, Map<Class<?>, List<String>>> missing = new HashMap<>(); - for (final Locale locale : Arrays.asList(Locale.ENGLISH, Locale.FRENCH)) { - final I18n i18n = new I18n(BUNDLE_NAME, locale); - final Enum<?>[] values = clazz.getEnumConstants(); - for (final Enum<?> value : values) { - final ErrorType k = (ErrorType) value; - final String tr = i18n.get(k.getI18nKey()); - if (tr.startsWith("!") && tr.endsWith("!")) { - missing.computeIfAbsent(locale, l -> new HashMap<>()); - missing.get(locale).computeIfAbsent(clazz, l -> new ArrayList<>()); - missing.get(locale).get(clazz).add(k.getI18nKey()); - } - } - } + final Map<Locale, Map<Class<?>, List<String>>> missing = ErrorTypeUtils.getMissingTranslations(clazz, + BUNDLE_NAME, List.of(Locale.ENGLISH, Locale.FRENCH)); assertTrue(missing.toString(), missing.isEmpty()); } @Test public void subCodeAreUnique() { - final Set<String> codes = new HashSet<>(); - final Set<String> duplicates = new HashSet<>(); - final Enum<?>[] values = clazz.getEnumConstants(); - for (final Enum<?> value : values) { - final ErrorType k = (ErrorType) value; - if (codes.contains(k.getSubCode())) { - duplicates.add(k.getSubCode()); - } - codes.add(k.getSubCode()); - } + final Set<String> duplicates = ErrorTypeUtils.getDuplicatedCodes(clazz); assertTrue(duplicates.isEmpty()); } } -- GitLab From 7fc224876173c354002c70704096f7ec7c753e9e Mon Sep 17 00:00:00 2001 From: Olivier Maury <Olivier.Maury@inrae.fr> Date: Thu, 4 Jan 2024 12:20:26 +0100 Subject: [PATCH 10/20] Lister les codes d'erreurs dans la documentation --- .gitlab-ci.yml | 14 + README.md | 2 +- pom.xml | 27 +- .../agroclim/indicators/GenerateMarkdown.java | 390 ++++++++++++++++++ .../exception/type/CommonErrorType.java | 6 + .../agroclim/indicators/model/Knowledge.java | 266 +----------- .../indicators/resources/messages.properties | 10 + .../resources/messages_fr.properties | 42 +- src/site/en/markdown/.gitignore | 3 + src/site/en/markdown/index.md.vm | 59 +++ src/site/markdown/.gitignore | 5 + src/site/markdown/index.md.vm | 16 +- src/site/site.xml | 4 + src/site/site_en.xml | 38 ++ .../IndicatorsErrorCategoryTest.java | 60 +++ 15 files changed, 651 insertions(+), 291 deletions(-) create mode 100644 src/main/java/fr/inrae/agroclim/indicators/GenerateMarkdown.java create mode 100644 src/site/en/markdown/.gitignore create mode 100644 src/site/en/markdown/index.md.vm create mode 100644 src/site/markdown/.gitignore create mode 100644 src/site/site_en.xml create mode 100644 src/test/java/fr/inrae/agroclim/indicators/exception/IndicatorsErrorCategoryTest.java diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 75197667..61201565 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -9,6 +9,7 @@ stages: - code-check - package - deploy + - pages cache: paths: @@ -65,3 +66,16 @@ deploy_job: - main script: - echo "Maven deploy started" + +pages_job: + stage: deploy + script: + - mvn exec:java -Dexec.mainClass=fr.inrae.agroclim.indicators.GenerateMarkdown -Dexec.args='${basedir}/src/site/markdown -' + - mv src/site/markdown/*-en.md src/site/en/markdown/ + - mvn site + - mv target/site public + artifacts: + paths: + - public + only: + - tags diff --git a/README.md b/README.md index 2b748cc0..f614643f 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ The library is used in the free software [GETARI](https://agroclim.inrae.fr/geta ## 🧠Features -It contains predefined indicators : 91 daily and 48 hourly. +It contains predefined indicators : 89 daily and 48 hourly. ## ðŸ› ï¸ Tech Stack diff --git a/pom.xml b/pom.xml index b20bf8e8..fe9f90b4 100644 --- a/pom.xml +++ b/pom.xml @@ -391,12 +391,23 @@ along with Indicators. If not, see <https://www.gnu.org/licenses/>. <artifactId>maven-deploy-plugin</artifactId> <version>2.8.2</version> </plugin> + <plugin> + <artifactId>maven-project-info-reports-plugin</artifactId> + <version>3.5.0</version> + </plugin> <plugin> <artifactId>maven-site-plugin</artifactId> <version>3.12.1</version> <configuration> - <locales>fr</locales> + <locales>fr,en</locales> </configuration> + <dependencies> + <dependency> + <groupId>org.apache.maven.doxia</groupId> + <artifactId>doxia-module-markdown</artifactId> + <version>2.0.0-M7</version> + </dependency> + </dependencies> </plugin> <!-- --> <plugin> @@ -517,6 +528,20 @@ along with Indicators. If not, see <https://www.gnu.org/licenses/>. <sourceFileExclude>module-info.*</sourceFileExclude> </sourceFileExcludes> </configuration> + <reportSets> + <reportSet> + <id>default</id> + <reports> + <report>javadoc</report> + </reports> + </reportSet> + <reportSet> + <id>aggregate</id> + <reports> + <report>aggregate</report> + </reports> + </reportSet> + </reportSets> </plugin> <!-- Include JaCoCo report into site --> diff --git a/src/main/java/fr/inrae/agroclim/indicators/GenerateMarkdown.java b/src/main/java/fr/inrae/agroclim/indicators/GenerateMarkdown.java new file mode 100644 index 00000000..6303dd3f --- /dev/null +++ b/src/main/java/fr/inrae/agroclim/indicators/GenerateMarkdown.java @@ -0,0 +1,390 @@ +package fr.inrae.agroclim.indicators; + +import fr.inrae.agroclim.indicators.exception.IndicatorsException; +import fr.inrae.agroclim.indicators.exception.type.CommonErrorType; +import fr.inrae.agroclim.indicators.exception.type.ComputationErrorType; +import fr.inrae.agroclim.indicators.exception.type.ResourceErrorType; +import fr.inrae.agroclim.indicators.exception.type.XmlErrorType; +import fr.inrae.agroclim.indicators.model.Knowledge; +import fr.inrae.agroclim.indicators.model.LocalizedString; +import fr.inrae.agroclim.indicators.model.Note; +import fr.inrae.agroclim.indicators.model.Parameter; +import fr.inrae.agroclim.indicators.model.TimeScale; +import fr.inrae.agroclim.indicators.model.indicator.CompositeIndicator; +import fr.inrae.agroclim.indicators.model.indicator.Indicator; +import fr.inrae.agroclim.indicators.resources.I18n; +import fr.inrae.agroclim.indicators.util.StringUtils; +import fr.inrae.agroclim.indicators.util.Utf8BufferedWriter; +import java.io.BufferedWriter; +import java.io.IOException; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Date; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Locale; +import java.util.Set; +import lombok.RequiredArgsConstructor; +import lombok.extern.log4j.Log4j2; + +/** + * Utility to create Markdown and CSV files for Hugo and Maven site. + * + * @author Olivier Maury + */ +@Log4j2 +@RequiredArgsConstructor +public class GenerateMarkdown { + + /** + * Mardown Yaml front matter. + */ + private static final String FRONT_MATTER = """ + --- + title: %s + description: %s + keywords: %s + date: %s + --- + + """; + /** + * Creation date for front matter. + */ + private String created; + + /** + * Separator between file base name and language code. + */ + private final String languageSep; + /** + * The directory where Markdown files are generated. + */ + private final String outDir; + + /** + * @param args arguments : outDir, languageSep + * @throws IndicatorsException while loading knowledge + * @throws java.io.IOException while writing file + */ + public static void main(final String[] args) throws IndicatorsException, IOException { + LOGGER.traceEntry("Arguments: {}", Arrays.asList(args)); + final String outDir; + final String languageSep; + if (args != null && args.length > 0) { + outDir = args[0]; + if (args.length > 1) { + languageSep = args[1]; + } else { + languageSep = "."; + } + } else { + outDir = System.getProperty("java.io.tmpdir"); + languageSep = "."; + } + var instance = new GenerateMarkdown(languageSep, outDir); + instance.run(); + } + + private void run() throws IndicatorsException, IOException { + final DateFormat df = new SimpleDateFormat("yyyy-MM-dd"); + created = df.format(new Date()); + + for (final Locale l : Arrays.asList(Locale.ENGLISH, Locale.FRENCH)) { + writeErrorMdFile(l); + } + for (final TimeScale timescale : TimeScale.values()) { + LOGGER.trace("Generating files for {}...", timescale); + final Knowledge knowledge = Knowledge.load(timescale); + for (final Locale l : Arrays.asList(Locale.ENGLISH, Locale.FRENCH)) { + writeIndicatorsMdFiles(knowledge, timescale, l); + } + writeIndicatorsCsvFiles(knowledge, timescale); + writeParametersCsvFiles(knowledge, timescale); + LOGGER.trace("Generating files for {}... done", timescale); + } + // TODO error codes + } + + /** + * Write the Markdown file showing all error codes and descriptions. + * + * @param locale locale for the strings + * @throws IOException file not found or error while writting + */ + private void writeErrorMdFile(final Locale locale) throws IOException { + final String languageCode = locale.getLanguage(); + final Path path = Paths.get(outDir, "errors" + languageSep + languageCode + ".md"); + final String bundleName = "fr.inrae.agroclim.indicators.resources.messages"; + final I18n i18n = new I18n(bundleName, locale); + LOGGER.trace(path); + try (BufferedWriter writer = new Utf8BufferedWriter(path)) { + writer.write(String.format(FRONT_MATTER, + i18n.get("markdown.error.title"), + i18n.get("markdown.error.description"), + i18n.get("markdown.error.keywords"), + created)); + writeLn(writer, i18n.get("markdown.error.fullcode"), i18n.get("markdown.error.name"), + i18n.get("markdown.error.message")); + writer.write("|:----------|:-----------|:-----------|\n"); + final List<CommonErrorType> types = new ArrayList<>(); + types.addAll(Arrays.asList(XmlErrorType.values())); + types.addAll(Arrays.asList(ResourceErrorType.values())); + types.addAll(Arrays.asList(ComputationErrorType.values())); + String previousCat = ""; + for (final CommonErrorType type : types) { + var cat = type.getCategory().getCategory(i18n); + if (!previousCat.equals(cat)) { + var catCode = type.getCategory().getCode(); + writeLn(writer, "**" + i18n.get("markdown.error.category") + " `" + catCode + "` - " + cat + "**"); + previousCat = cat; + } + var fullCode = type.getFullCode(); + var name = type.getName(); + var description = i18n.get(type.getI18nKey()); + writeLn(writer, fullCode, name, description); + } + } + } + + /** + * @param knowledge knowledge to export as files + * @param timescale timescale of related indicators + * @throws IOException + */ + private void writeIndicatorsCsvFiles(final Knowledge knowledge, final TimeScale timescale) throws IOException { + final String suffix = "-" + timescale.name().toLowerCase(); + final Path path = Paths.get(outDir, "indicators" + suffix + ".csv"); + LOGGER.trace(path); + try (BufferedWriter writer = new Utf8BufferedWriter(path)) { + writer.write("id;nom_en;nom_fr;description_en;description_fr;variables;param\u00e8tres;notes\n"); + for (final CompositeIndicator comp : knowledge.getIndicators()) { + for (final Indicator ind : comp.getIndicators()) { + writer.write(ind.getId()); + writer.write(";"); + writer.write(ind.getName("en")); + writer.write(";"); + if (!ind.getName("fr").equals(ind.getName("en"))) { + writer.write(ind.getName("fr")); + } + writer.write(";"); + final String description = ind.getDescription("fr"); + if (!description.equals(ind.getDescription("en"))) { + writer.write(ind.getDescription("en")); + } + writer.write(";"); + writer.write(description); + writer.write(";"); + final List<String> variables = new LinkedList<>(); + if (ind.getVariables() != null && !ind.getVariables().isEmpty()) { + ind.getVariables().forEach(variable -> variables.add(variable.getName())); + Collections.sort(variables); + writer.write(String.join(", ", variables)); + } + writer.write(";"); + final List<String> parameters = new LinkedList<>(); + if (ind.getParameters() != null + && !ind.getParameters().isEmpty()) { + ind.getParameters().forEach(param -> parameters.add(param.getId())); + Collections.sort(parameters); + writer.write(String.join(", ", parameters)); + } + // affichage des références des notes de l'indicateurs + writer.write(";"); + final List<String> notes = new LinkedList<>(); + if (ind.getNotes() != null && !ind.getNotes().isEmpty()) { + ind.getNotes().forEach(note -> notes.add(note.getId())); + writer.write(String.join(", ", notes)); + } + writer.write("\n"); + } + } + } + } + + /** + * @param knowledge knowledge to export as files + * @param timescale timescale of related indicators + * @param locale locale to write + * @throws IOException + */ + private void writeIndicatorsMdFiles(final Knowledge knowledge, final TimeScale timescale, final Locale locale) + throws IOException { + final String languageCode = locale.getLanguage(); + final String suffix = "-" + timescale.name().toLowerCase(); + final Path mdPath = Paths.get(outDir, "indicators" + suffix + languageSep + languageCode + ".md"); + final String bundleName = "fr.inrae.agroclim.indicators.resources.messages"; + final I18n i18n = new I18n(bundleName, locale); + + LOGGER.trace(mdPath); + try (BufferedWriter mdWriter = new Utf8BufferedWriter(mdPath);) { + final long nb = knowledge.getIndicators().stream().mapToInt(comp -> comp.getIndicators().size()).sum(); + final String indicatorsVersion = fr.inrae.agroclim.indicators.resources.Version.getString("version"); + final String frontMatter = """ + --- + title: %s + description: %s + keywords: %s + date: %s + --- + + """; + mdWriter.write(String.format(frontMatter, + i18n.get("markdown.title." + timescale.name().toLowerCase()), + i18n.get("markdown.description." + timescale.name().toLowerCase()), + i18n.get("markdown.keywords"), + created)); + mdWriter.write(i18n.format("markdown.indicators.version", indicatorsVersion) + "\n\n" + + "## " + i18n.format("markdown.indicators." + timescale.name().toLowerCase(), nb) + "\n"); + writeLn(mdWriter, i18n.get("markdown.id"), i18n.get("markdown.name"), i18n.get("markdown.description"), + i18n.get("markdown.variables"), i18n.get("markdown.parameters"), + i18n.get("markdown.unit") + " [^1]", i18n.get("markdown.notes")); + mdWriter.write("|:---|:-----|:------------|:----------|:-----------|:-----------|:-----------|\n"); + + final Set<String> allVariables = new HashSet<>(); + for (final CompositeIndicator comp : knowledge.getIndicators()) { + writeLn(mdWriter, "**" + comp.getName(languageCode) + "**"); + for (final Indicator ind : comp.getIndicators()) { + final List<String> variables = new LinkedList<>(); + if (ind.getVariables() != null + && !ind.getVariables().isEmpty()) { + ind.getVariables().forEach(variable -> variables.add(variable.getName())); + Collections.sort(variables); + allVariables.addAll(variables); + } + final List<String> parameters = new LinkedList<>(); + if (ind.getParameters() != null + && !ind.getParameters().isEmpty()) { + ind.getParameters().forEach(param -> parameters.add(param.getId())); + Collections.sort(parameters); + } + String unit = ""; + if (ind.getUnit() != null) { + List<LocalizedString> symbols = ind.getUnit().getSymbols(); + if (symbols != null && !symbols.isEmpty()) { + unit = LocalizedString.getString(symbols, languageCode); + } + if (unit == null || unit.isBlank()) { + final List<LocalizedString> labels = ind.getUnit().getLabels(); + if (labels != null && !labels.isEmpty()) { + unit = LocalizedString.getString(labels, languageCode); + } + } + } + // affichage des références des notes de l'indicateurs + final List<String> notes = new LinkedList<>(); + if (ind.getNotes() != null && !ind.getNotes().isEmpty()) { + ind.getNotes().forEach(note -> { + final String anchor = note.getId(); + notes.add("<a href='#" + anchor + "'>" + note.getId() + "</a>"); + }); + } + writeLn(mdWriter, ind.getId(), ind.getName(languageCode), + ind.getDescription(languageCode), String.join(", ", variables), + String.join(", ", parameters), unit, String.join(", ", notes)); + } + } + + mdWriter.write(""" + + ###\s""" + i18n.get("markdown.parameters") + "\n" + + "| " + i18n.get("markdown.id") + " | " + i18n.get("markdown.description") + " |\n" + + "|:---|:------------|\n"); + + for (final Parameter param : knowledge.getParameters()) { + writeLn(mdWriter, param.getId(), param.getDescription(languageCode)); + } + + mdWriter.write(""" + + ###\s""" + i18n.get("markdown.variables") + "\n" + + "| " + i18n.get("markdown.id") + " | " + i18n.get("markdown.description") + " |\n" + + "|:---|:------------|\n"); + allVariables.stream().sorted().forEach(variable -> { + try { + mdWriter.write("| "); + mdWriter.write(variable); + mdWriter.write(" | "); + mdWriter.write(i18n.get("Variable." + variable.toUpperCase() + ".description")); + mdWriter.write(" |\n"); + } catch (final IOException ex) { + LOGGER.catching(ex); + } + }); + + // Ecriture de l'ensemble des notes présentes + if (knowledge.getNotes() != null && !knowledge.getNotes().isEmpty()) { + mdWriter.write(""" + + ###\s""" + i18n.get("markdown.notes") + "\n" + + "| " + i18n.get("markdown.reference") + " | " + i18n.get("markdown.description") + " |\n" + + "|:---|:------------|\n"); + for (final Note note : knowledge.getNotes()) { + final String anchor; + + // si il s'agit d'un DOI, on affiche le lien + final String id = note.getId(); + if (StringUtils.isDoiRef(id)) { + anchor = String.format( + "<a id=\"%1$s\" href=\"https://doi.org/%1$s\" target=\"_blank\">%1$s</a>", + id); + } else { + anchor = String.format("<a id=\"%1$s\">%1$s</a>", id); + } + + writeLn(mdWriter, anchor, note.getDescription()); + } + } + + mdWriter.write("\n\n[^1]: " + i18n.get("markdown.unit.footnote")); + } + } + + /** + * Write a line in a table. + * + * @param writer the writer to user + * @param values strings to write + * @throws IOException when using BufferedWriter.write + */ + private static void writeLn(final BufferedWriter writer, + final String... values) throws IOException { + final int nb = values.length; + writer.write("| "); + for (int i = 0; i < nb; i++) { + writer.write(values[i]); + if (i < nb - 1) { + writer.write(" | "); + } + } + writer.write(" |\n"); + } + + /** + * @param knowledge knowledge to export as files + * @param timescale timescale of related indicators + * @throws IOException + */ + private void writeParametersCsvFiles(final Knowledge knowledge, final TimeScale timescale) throws IOException { + final String suffix = "-" + timescale.name().toLowerCase(); + final Path paramPath = Paths.get(outDir, "parameters" + suffix + ".csv"); + LOGGER.trace(paramPath); + try (BufferedWriter paramWriter = new Utf8BufferedWriter(paramPath)) { + paramWriter.write("id;description_fr;description_en\n"); + for (final Parameter param : knowledge.getParameters()) { + paramWriter.write(param.getId()); + paramWriter.write(";"); + paramWriter.write(param.getDescription("fr")); + paramWriter.write(";"); + paramWriter.write(param.getDescription("en")); + paramWriter.write("\n"); + } + } + } +} diff --git a/src/main/java/fr/inrae/agroclim/indicators/exception/type/CommonErrorType.java b/src/main/java/fr/inrae/agroclim/indicators/exception/type/CommonErrorType.java index b500fab0..8db6e449 100644 --- a/src/main/java/fr/inrae/agroclim/indicators/exception/type/CommonErrorType.java +++ b/src/main/java/fr/inrae/agroclim/indicators/exception/type/CommonErrorType.java @@ -16,8 +16,14 @@ public interface CommonErrorType extends ErrorType { return getName().toLowerCase().replace("_", "."); } + /** + * @return parent error + */ CommonErrorType getParent(); + /** + * @return error name (as {@link Enum#name()). + */ String name(); /** diff --git a/src/main/java/fr/inrae/agroclim/indicators/model/Knowledge.java b/src/main/java/fr/inrae/agroclim/indicators/model/Knowledge.java index 741c8993..637484e0 100644 --- a/src/main/java/fr/inrae/agroclim/indicators/model/Knowledge.java +++ b/src/main/java/fr/inrae/agroclim/indicators/model/Knowledge.java @@ -17,24 +17,11 @@ package fr.inrae.agroclim.indicators.model; import fr.inrae.agroclim.indicators.exception.IndicatorsException; -import java.io.BufferedWriter; -import java.io.IOException; import java.io.InputStream; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.text.DateFormat; -import java.text.SimpleDateFormat; import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.Date; import java.util.EnumMap; -import java.util.HashSet; -import java.util.LinkedList; import java.util.List; -import java.util.Locale; import java.util.Map; -import java.util.Set; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; @@ -75,9 +62,6 @@ import fr.inrae.agroclim.indicators.model.indicator.Quotient; import fr.inrae.agroclim.indicators.model.indicator.SimpleIndicator; import fr.inrae.agroclim.indicators.model.indicator.Sum; import fr.inrae.agroclim.indicators.model.indicator.Tamm; -import fr.inrae.agroclim.indicators.resources.I18n; -import fr.inrae.agroclim.indicators.util.StringUtils; -import fr.inrae.agroclim.indicators.util.Utf8BufferedWriter; import fr.inrae.agroclim.indicators.xml.XMLUtil; import javax.xml.bind.annotation.XmlAttribute; import lombok.Getter; @@ -89,10 +73,7 @@ import lombok.extern.log4j.Log4j2; /** * knowledge.xml. * - * Last change $Date$ - * - * @author $Author$ - * @version $Revision$ + * @author Olivier Maury */ @XmlRootElement @XmlAccessorType(XmlAccessType.FIELD) @@ -196,251 +177,6 @@ public final class Knowledge implements Cloneable { return load(stream); } - /** - * @param args not used - * @throws IndicatorsException while loading knowledge - * @throws java.io.IOException while writing file - */ - public static void main(final String[] args) throws IndicatorsException, - IOException { - for (final TimeScale timescale: TimeScale.values()) { - LOGGER.trace("Generating files for {}...", timescale); - final Knowledge knowledge = Knowledge.load(timescale); - for (final Locale l: Arrays.asList(Locale.ENGLISH, Locale.FRENCH)) { - writeMarkDownFiles(knowledge, timescale, l); - } - writeFiles(knowledge, timescale); - LOGGER.trace("Generating files for {}... done", timescale); - } - } - /** - * @param knowledge knowledge to export as files - * @param timescale timescale of related indicators - * @throws IOException - */ - private static void writeFiles(final Knowledge knowledge, final TimeScale timescale) throws IOException { - final String suffix = "-" + timescale.name().toLowerCase(); - final String tmpDir = System.getProperty("java.io.tmpdir"); - final Path path = Paths.get(tmpDir, "indicators" + suffix + ".csv"); - final Path paramPath = Paths.get(tmpDir, "parameters" + suffix + ".csv"); - LOGGER.trace(path); - LOGGER.trace(paramPath); - try ( - BufferedWriter writer = new Utf8BufferedWriter(path); - BufferedWriter paramWriter = new Utf8BufferedWriter(paramPath);) { - writer.write(""" - id;nom_en;nom_fr;description_en;description_fr;variables;param\u00e8tres;notes - """); - for (final CompositeIndicator comp : knowledge.getIndicators()) { - for (final Indicator ind : comp.getIndicators()) { - writer.write(ind.getId()); - writer.write(";"); - writer.write(ind.getName("en")); - writer.write(";"); - if (!ind.getName("fr").equals(ind.getName("en"))) { - writer.write(ind.getName("fr")); - } - writer.write(";"); - final String description = ind.getDescription("fr"); - if (!description.equals(ind.getDescription("en"))) { - writer.write(ind.getDescription("en")); - } - writer.write(";"); - writer.write(description); - writer.write(";"); - final List<String> variables = new LinkedList<>(); - if (ind.getVariables() != null - && !ind.getVariables().isEmpty()) { - ind.getVariables().forEach(variable -> variables.add(variable.getName())); - Collections.sort(variables); - writer.write(String.join(", ", variables)); - } - writer.write(";"); - final List<String> parameters = new LinkedList<>(); - if (ind.getParameters() != null - && !ind.getParameters().isEmpty()) { - ind.getParameters().forEach(param -> parameters.add(param.getId())); - Collections.sort(parameters); - writer.write(String.join(", ", parameters)); - } - // affichage des références des notes de l'indicateurs - writer.write(";"); - final List<String> notes = new LinkedList<>(); - if (ind.getNotes() != null && !ind.getNotes().isEmpty()) { - ind.getNotes().forEach(note -> notes.add(note.getId())); - writer.write(String.join(", ", notes)); - } - writer.write("\n"); - } - } - paramWriter.write("id;description_fr;description_en\n"); - for (final Parameter param : knowledge.getParameters()) { - paramWriter.write(param.getId()); - paramWriter.write(";"); - paramWriter.write(param.getDescription("fr")); - paramWriter.write(";"); - paramWriter.write(param.getDescription("en")); - paramWriter.write("\n"); - } - } - } - - /** - * Write a line. - * - * @param writer the writer to user - * @param values strings to write - * @throws IOException when using BufferedWriter.write - */ - private static void writeLn(final BufferedWriter writer, - final String... values) throws IOException { - final int nb = values.length; - writer.write("| "); - for (int i = 0; i < nb; i++) { - writer.write(values[i]); - if (i < nb - 1) { - writer.write(" | "); - } - } - writer.write(" |\n"); - } - - /** - * @param knowledge knowledge to export as files - * @param timescale timescale of related indicators - * @param locale locale to write - * @throws IOException - */ - private static void writeMarkDownFiles(final Knowledge knowledge, final TimeScale timescale, final Locale locale) - throws IOException { - final String languageCode = locale.getLanguage(); - final String suffix = "-" + timescale.name().toLowerCase(); - final String tmpDir = System.getProperty("java.io.tmpdir"); - final Path mdPath = Paths.get(tmpDir, "indicators" + suffix + "." + languageCode + ".md"); - final String bundleName = "fr.inrae.agroclim.indicators.resources.messages"; - final I18n i18n = new I18n(bundleName, locale); - - final DateFormat df = new SimpleDateFormat("yyyy-MM-dd"); - final String created = df.format(new Date()); - - LOGGER.trace(mdPath); - try (BufferedWriter mdWriter = new Utf8BufferedWriter(mdPath);) { - final long nb = knowledge.getIndicators().stream().mapToInt(comp -> comp.getIndicators().size()).sum(); - final String indicatorsVersion = fr.inrae.agroclim.indicators.resources.Version.getString("version"); - mdWriter.write("+++\n" - + "# $Id: $\n" - + "title = \"" + i18n.get("markdown.title." + timescale.name().toLowerCase()) + "\"\n" - + "description = \"" + i18n.get("markdown.description." + timescale.name().toLowerCase()) + "\"\n" - + "keywords = [" + i18n.get("markdown.keywords") + "]\n" - + "date = " + created + "\n" - + "+++\n" - + i18n.format("markdown.indicators.version", indicatorsVersion) + "\n\n" - + "## " + i18n.format("markdown.indicators." + timescale.name().toLowerCase(), nb) + "\n" - + "| " + String.join(" | ", - i18n.get("markdown.id"), i18n.get("markdown.name"), i18n.get("markdown.description"), - i18n.get("markdown.variables"), i18n.get("markdown.parameters"), - i18n.get("markdown.unit") + " [^1]", i18n.get("markdown.notes")) + " |\n" - + "|:---|:-----|:------------|:----------|:-----------|:-----------|:-----------|\n"); - - final Set<String> allVariables = new HashSet<>(); - for (final CompositeIndicator comp : knowledge.getIndicators()) { - writeLn(mdWriter, "**" + comp.getName(languageCode) + "**"); - for (final Indicator ind : comp.getIndicators()) { - final List<String> variables = new LinkedList<>(); - if (ind.getVariables() != null - && !ind.getVariables().isEmpty()) { - ind.getVariables().forEach(variable -> variables.add(variable.getName())); - Collections.sort(variables); - allVariables.addAll(variables); - } - final List<String> parameters = new LinkedList<>(); - if (ind.getParameters() != null - && !ind.getParameters().isEmpty()) { - ind.getParameters().forEach(param -> parameters.add(param.getId())); - Collections.sort(parameters); - } - String unit = ""; - if (ind.getUnit() != null) { - List<LocalizedString> symbols = ind.getUnit().getSymbols(); - if (symbols != null && !symbols.isEmpty()) { - unit = LocalizedString.getString(symbols, languageCode); - } - if (unit == null || unit.isBlank()) { - final List<LocalizedString> labels = ind.getUnit().getLabels(); - if (labels != null && !labels.isEmpty()) { - unit = LocalizedString.getString(labels, languageCode); - } - } - } - // affichage des références des notes de l'indicateurs - final List<String> notes = new LinkedList<>(); - if (ind.getNotes() != null && !ind.getNotes().isEmpty()) { - ind.getNotes().forEach(note -> { - final String anchor = note.getId(); - notes.add("<a href='#" + anchor + "'>" + note.getId() + "</a>"); - }); - } - writeLn(mdWriter, ind.getId(), ind.getName(languageCode), - ind.getDescription(languageCode), String.join(", ", variables), - String.join(", ", parameters), unit, String.join(", ", notes)); - } - } - - mdWriter.write(""" - - ###\s""" + i18n.get("markdown.parameters") + "\n" - + "| " + i18n.get("markdown.id") + " | " + i18n.get("markdown.description") + " |\n" - + "|:---|:------------|\n"); - - for (final Parameter param : knowledge.getParameters()) { - writeLn(mdWriter, param.getId(), param.getDescription(languageCode)); - } - - mdWriter.write(""" - - ###\s""" + i18n.get("markdown.variables") + "\n" - + "| " + i18n.get("markdown.id") + " | " + i18n.get("markdown.description") + " |\n" - + "|:---|:------------|\n"); - allVariables.stream().sorted().forEach(variable -> { - try { - mdWriter.write("| "); - mdWriter.write(variable); - mdWriter.write(" | "); - mdWriter.write(i18n.get("Variable." + variable.toUpperCase() + ".description")); - mdWriter.write(" |\n"); - } catch (final IOException ex) { - LOGGER.catching(ex); - } - }); - - // Ecriture de l'ensemble des notes présentes - if (knowledge.getNotes() != null && !knowledge.getNotes().isEmpty()) { - mdWriter.write(""" - - ###\s""" + i18n.get("markdown.notes") + "\n" - + "| " + i18n.get("markdown.reference") + " | " + i18n.get("markdown.description") + " |\n" - + "|:---|:------------|\n"); - for (final Note note : knowledge.getNotes()) { - final String anchor; - - // si il s'agit d'un DOI, on affiche le lien - final String id = note.getId(); - if (StringUtils.isDoiRef(id)) { - anchor = String.format( - "<a id=\"%1$s\" href=\"https://doi.org/%1$s\" target=\"_blank\">%1$s</a>", - id); - } else { - anchor = String.format("<a id=\"%1$s\">%1$s</a>", id); - } - - writeLn(mdWriter, anchor, note.getDescription()); - } - } - - mdWriter.write("\n\n[^1]: " + i18n.get("markdown.unit.footnote")); - } - } - /** * Indicators for cultural practices. */ diff --git a/src/main/resources/fr/inrae/agroclim/indicators/resources/messages.properties b/src/main/resources/fr/inrae/agroclim/indicators/resources/messages.properties index 72ec24e6..441aca5a 100644 --- a/src/main/resources/fr/inrae/agroclim/indicators/resources/messages.properties +++ b/src/main/resources/fr/inrae/agroclim/indicators/resources/messages.properties @@ -15,6 +15,9 @@ # along with Indicators. If not, see <https://www.gnu.org/licenses/>. # #Errors +error.category.computation=Evaluation computation +error.category.resources=Evaluation resources +error.category.xml=XML parsing error.climate.jdbc.query=Error while query execution "{0}"! error.climate.dates=For the year {0}, available dates are from {1} to {2}. error.climate.no.data=No data were retrieved. @@ -99,6 +102,13 @@ markdown.description.hourly=List of available indicators at hourly timescale markdown.title.daily=Indicators at daily timescale markdown.title.hourly=Indicators at hourly timescale markdown.keywords="indicator","agroclimatic","ecoclimatic" +markdown.error.category=Category +markdown.error.description=List of error types: codes and descriptions. +markdown.error.fullcode=Error code +markdown.error.keywords="library","error codes" +markdown.error.message=Error message +markdown.error.name=Error name +markdown.error.title=Error types markdown.indicators=Indicators markdown.indicators.daily={0} daily indicators markdown.indicators.hourly={0} hourly indicators diff --git a/src/main/resources/fr/inrae/agroclim/indicators/resources/messages_fr.properties b/src/main/resources/fr/inrae/agroclim/indicators/resources/messages_fr.properties index b43f027f..afbe1374 100644 --- a/src/main/resources/fr/inrae/agroclim/indicators/resources/messages_fr.properties +++ b/src/main/resources/fr/inrae/agroclim/indicators/resources/messages_fr.properties @@ -20,27 +20,30 @@ warning.soilcalculator.4stages[none]=Aucun stade ph\u00e9nologique n\u2019est fo warning.soilcalculator.4stages[one]=Un stade ph\u00e9nologique est fourni, mais le calcul du bilan hydrique en n\u00e9cessite 4\u00a0! warning.soilloader.missing=La configuration pour le calcul du bilan hydrique manque alors que des indicateurs portent sur la teneur en eau du sol ou la r\u00e9serve utile. warning.tmax.inferiorto.tmin={0}\u00a0: ligne {1}\u00a0: la temp\u00e9rature minimale doit \u00eatre inf\u00e9rieure \u00e0 la temp\u00e9rature maximale. +error.category.computation=Calcul de l\u2019\u00e9valuation +error.category.resources=Ressources de l\u2019\u00e9valuation +error.category.xml=Lecture du fichier XML error.climate.dates=Pour l\u2019ann\u00e9e {0}, les dates lues vont du {1} au {2}. error.climate.no.data=Aucune donn\u00e9e n\u2019a \u00e9t\u00e9 r\u00e9cup\u00e9r\u00e9e. -error.climate.wrong.headers=Mauvais nombre d\u2019ent\u00eates\u00a0! {0} ent\u00eates sont dans le fichier : {1}, mais {2} ent\u00eates sont d\u00e9finis : {3}. +error.climate.wrong.headers=Mauvais nombre d\u2019ent\u00eates\u00a0! {0} ent\u00eates sont dans le fichier\u00a0: {1}, mais {2} ent\u00eates sont d\u00e9finis\u00a0: {3}. error.computation.formula.aggregation.null=L\u2019agr\u00e9gation ne peut \u00eatre nulle. -error.computation.formula=Erreur lors de l\u2019ex\u00e9cution de l\u2019expression \u00ab {0} \u00bb. +error.computation.formula=Erreur lors de l\u2019ex\u00e9cution de l\u2019expression \u00ab\u00a0{0}\u00a0\u00bb. error.computation.formula.expression.blank=L\u2019expression ne peut \u00eatre vide. error.computation.formula.expression.null=L\u2019expression ne peut \u00eatre nulle. -error.computation.formula.expression.parenthesis=Expression non valide \u00ab {0} \u00bb : des parenth\u00e8ses manquent. -error.computation.formula.expression.parsing=Expression non valide \u00ab {0} \u00bb : erreur d\u2019analyse. -error.computation.formula.function.unknown=Expression non valide \u00ab {0} \u00bb : la fonction \u00ab {1} \u00bb est inconnue ou ambig\u00fce. Si la fonction existe, v\u00e9rifiez les arguments. -error.computation.formula.variable.undefined=Expression non valide \u00ab {0} \u00bb : la variable \u00ab {1} \u00bb n\u2019est pas d\u00e9finie. +error.computation.formula.expression.parenthesis=Expression non valide \u00ab\u00a0{0}\u00a0\u00bb\u00a0: des parenth\u00e8ses manquent. +error.computation.formula.expression.parsing=Expression non valide \u00ab\u00a0{0}\u00a0\u00bb\u00a0: erreur d\u2019analyse. +error.computation.formula.function.unknown=Expression non valide \u00ab\u00a0{0}\u00a0\u00bb\u00a0: la fonction \u00ab\u00a0{1}\u00a0\u00bb est inconnue ou ambig\u00fce. Si la fonction existe, v\u00e9rifiez les arguments. +error.computation.formula.variable.undefined=Expression non valide \u00ab\u00a0{0}\u00a0\u00bb\u00a0: la variable \u00ab\u00a0{1}\u00a0\u00bb n\u2019est pas d\u00e9finie. error.computation.input=Le calcul de l\u2019indicateur a \u00e9chou\u00e9 \u00e0 cause d\u2019une entr\u00e9e invalide. -error.computation.input.composite.computation=Le calcul d\u2019un indicateur composant \u00ab {0} \u00bb a \u00e9chou\u00e9. +error.computation.input.composite.computation=Le calcul d\u2019un indicateur composant \u00ab\u00a0{0}\u00a0\u00bb a \u00e9chou\u00e9. error.computation.input.data.null=Les donn\u00e9es journali\u00e8res ne doivent pas \u00eatre nulles. -error.computation.input.quotient.dividend.exception=Le calcul de l\u2019indicateur num\u00e9rateur \u00ab {0} \u00bb dans Quotient a \u00e9chou\u00e9. -error.computation.input.quotient.divisor.exception=Le calcul de l\u2019indicateur d\u00e9nominateur \u00ab {0} \u00bb dans Quotient a \u00e9chou\u00e9. -error.computation.input.quotient.divisor.zero=Le r\u00e9sultat du calcul de l\u2019indicateur d\u00e9nominateur \u00ab {0} \u00bb est z\u00e9ro. -error.computation.input.variable.value.null=La valeur de la variable \u00ab {0} \u00bb ne doit pas \u00eatre nulle le \u00ab {1} \u00bb. -error.computation.wrong.definition.criteria.isnt.nocriteria.simplecriteria=criteria n\u2019est ni NoCriteria ni SimpleCriteria\u00a0! -error.computation.wrong.definition.criteria.null=La propri\u00e9t\u00e9 \u00ab criteria \u00bb ne doit pas \u00eatre nulle. -error.computation.wrong.definition=L\u2019indicateur \u00ab {0} \u00bb n\u2019est pas bien d\u00e9fini : {1}. +error.computation.input.quotient.dividend.exception=Le calcul de l\u2019indicateur num\u00e9rateur \u00ab\u00a0{0}\u00a0\u00bb dans Quotient a \u00e9chou\u00e9. +error.computation.input.quotient.divisor.exception=Le calcul de l\u2019indicateur d\u00e9nominateur \u00ab\u00a0{0}\u00a0\u00bb dans Quotient a \u00e9chou\u00e9. +error.computation.input.quotient.divisor.zero=Le r\u00e9sultat du calcul de l\u2019indicateur d\u00e9nominateur \u00ab\u00a0{0}\u00a0\u00bb est z\u00e9ro. +error.computation.input.variable.value.null=La valeur de la variable \u00ab\u00a0{0}\u00a0\u00bb ne doit pas \u00eatre nulle pour le jour \u00ab\u00a0{1}\u00a0\u00bb. +error.computation.wrong.definition.criteria.isnt.nocriteria.simplecriteria=La propri\u00e9t\u00e9 \u00ab\u00a0criteria\u00a0\u00bb n\u2019est ni NoCriteria ni SimpleCriteria\u00a0! +error.computation.wrong.definition.criteria.null=La propri\u00e9t\u00e9 \u00ab\u00a0criteria\u00a0\u00bb ne doit pas \u00eatre nulle. +error.computation.wrong.definition=L\u2019indicateur \u00ab\u00a0{0}\u00a0\u00bb n\u2019est pas bien d\u00e9fini\u00a0: {1}. error.computation.wrong.definition.quotient.dividend.null=L\u2019indicateur num\u00e9rateur ne doit pas \u00eatre nul. error.computation.wrong.definition.quotient.divisor.null=L\u2019indicateur d\u00e9nominateur ne doit pas \u00eatre nul. error.computation.wrong.definition.threshold.null=Le seuil ne doit pas \u00eatre null. @@ -92,6 +95,13 @@ markdown.description.hourly=Liste des indicateurs disponibles au pas de temps ho markdown.title.daily=Indicateurs au pas de temps journalier markdown.title.hourly=Indicateurs au pas de temps horaire markdown.keywords="indicateur","agroclimatique","\u00e9coclimatique" +markdown.error.category=Cat\u00e9gorie +markdown.error.description=Liste des erreurs\u00a0: codes et descriptions. +markdown.error.fullcode=Code d\u2019erreur +markdown.error.keywords="biblioth\u00e8que","code d\u2019erreur" +markdown.error.message=Message d\u2019erreur +markdown.error.name=Nom de l\u2019erreur +markdown.error.title=Codes d\u2019erreurs markdown.indicators=Indicateurs markdown.indicators.daily={0} indicateurs journaliers markdown.indicators.hourly={0} indicateurs horaires @@ -117,7 +127,7 @@ EvaluationType.WITH_AGGREGATION.name=avec agr\u00e9gation EvaluationType.WITHOUT_AGGREGATION.name=sans agr\u00e9gation MathMethod.avg.description = Renvoie la moyenne des valeurs pass\u00e9es en param\u00e8tre de la fonction. -MathMethod.exp.description = Renvoie le nombre Euler e \u00e9lev\u00e9 \u00e0 la puissance d\u2019une valeur double. Cas sp\u00e9ciaux :\n\n\ +MathMethod.exp.description = Renvoie le nombre Euler e \u00e9lev\u00e9 \u00e0 la puissance d\u2019une valeur double. Cas sp\u00e9ciaux\u00a0:\n\n\ Si l\u2019argument est NaN, le r\u00e9sultat est NaN.\n\ Si l\u2019argument in l\u2019infini positif, le r\u00e9sultat est l\u2019infini positif.\n\ Si l\u2019argument in l\u2019infini n\u00e9gatif, le r\u00e9sultat est z\u00e9ro positif.\n\ @@ -156,6 +166,6 @@ Variable.RH.description=Humidit\u00e9 relative [%]. Variable.SOILWATERCONTENT.description=Teneur en eau du sol [% massique]. Variable.WATER_RESERVE.description=R\u00e9serve en eau du sol [mm]. Variable.WIND.description=Vitesse du vent [m/s]. -error.xml.file.not.found=Le fichier XML \u00ab {0} \u00bb n\u2019a pas \u00e9t\u00e9 trouv\u00e9. +error.xml.file.not.found=Le fichier XML \u00ab\u00a0{0}\u00a0\u00bb n\u2019a pas \u00e9t\u00e9 trouv\u00e9. error.xml.unable.to.load=Le chargement du fichier XML a \u00e9chou\u00e9. error.xml.unable.to.serialize=La s\u00e9rialisation du fichier XML a \u00e9chou\u00e9. diff --git a/src/site/en/markdown/.gitignore b/src/site/en/markdown/.gitignore new file mode 100644 index 00000000..62c71ef0 --- /dev/null +++ b/src/site/en/markdown/.gitignore @@ -0,0 +1,3 @@ +errors-en.md +indicators-daily-en.md +indicators-hourly-en.md diff --git a/src/site/en/markdown/index.md.vm b/src/site/en/markdown/index.md.vm new file mode 100644 index 00000000..262e036e --- /dev/null +++ b/src/site/en/markdown/index.md.vm @@ -0,0 +1,59 @@ +#set($h1 = '#') +#set($h2 = '##') +#set($h3 = '###') +#set($h4 = '####') +<head> + <title>Technical documenation for de ${project.name}</title> +</head> + +$h1 Technical documentation for ${project.name} + +Indicator library, usable in eco-climatic mode (with an embeddded phenological model) as well as agro-climatic. +This library is used by the desktop software [GETARI](https://agroclim.inrae.fr/getari/en/) and the workflow SEASON embeeded into [SICLIMA](https://agroclim.inrae.fr/siclima/). + +$h2 Project links: + +- [Project info](project-info.html): information about code management, issues and bugs managnements, and continuous integration server. +- [Dependencies](dependencies.html). +- [Project license](license.html): from the tag `<licenses>` in the file `pom.xml`. + +$h2 Code structuration + +Source code is divided as: + +- `pom.xml`: Maven file +- `src/main/` : source code +- `src/test/` : source code for tests +- `src/site/` : documentation, see below + +$h3 Documentation + +Documentation is writtent in the folder `/src/site/markdown/`. +Site structure is defined in `/src/site/site_en.xml`. +Plain text formats are prefered to allow SCM. +This document is writtent in Markdown format. + +UML diagrams are written in [PlantUML](http://plantuml.com/) format +(extension `.puml` in `/src/site/resources/images/`). +The prefixes for the diagrams: + +- `act-` : activity diagrams +- `cas-` : use case diagrams +- `cls-` : class diagrams +- `cmp-` : component diagrams +- `seq-` : sequence diagrams + +The technical documentation is generated by Maven. +The Markdown files showing indicators and error codes are generated by the class `GenerateMarkdown`. + +``` +mvn exec:java -Dexec.mainClass=fr.inrae.agroclim.indicators.GenerateMarkdown -Dexec.args='${basedir}/src/site/markdown -' +mvn site +``` + +Jetty can be used for real time rendering, +so refreshing the browser shows the changes: use `mvn site:run` and visit the link, +usually http://localhost:8080/. + +If needed, generate the UML diagrams using +`mvn com.github.jeluard:plantuml-maven-plugin:generate`. diff --git a/src/site/markdown/.gitignore b/src/site/markdown/.gitignore new file mode 100644 index 00000000..e533f96d --- /dev/null +++ b/src/site/markdown/.gitignore @@ -0,0 +1,5 @@ +errors-*.md +indicators-daily* +indicators-hourly* +parameters-daily.csv +parameters-hourly.csv diff --git a/src/site/markdown/index.md.vm b/src/site/markdown/index.md.vm index 535955ae..071b957d 100644 --- a/src/site/markdown/index.md.vm +++ b/src/site/markdown/index.md.vm @@ -8,7 +8,7 @@ $h1 Documentation technique de ${project.name} -Bibliothèque d'indicateurs, utilisable autant en mode éco-climatique (avec modèle phénologique intégré) qu'enen mode agro-climatique. +Bibliothèque d'indicateurs, utilisable autant en mode éco-climatique (avec modèle phénologique intégré) qu'en mode agro-climatique. Cette bibliothèque est utilisée dans le logiciel de bureau [GETARI](https://agroclim.inrae.fr/getari/) et la chaîne de traitement SEASON intégrée dans [SICLIMA](https://agroclim.inrae.fr/siclima/). $h2 Liens du projet : @@ -43,7 +43,13 @@ Voici les préfixes pour les diagrammes : - `cmp-` : diagrammes de composants - `seq-` : diagrammes de séquence -La documentation technique est générée par Maven avec la commande `mvn site`. +La documentation technique est générée par Maven. +Les fichiers Markdown listant les indicateurs et les codes d'erreur sont générés par la classe `GenerateMarkdown`. + +``` +mvn exec:java -Dexec.mainClass=fr.inrae.agroclim.indicators.GenerateMarkdown -Dexec.args='${basedir}/src/site/markdown -' +mvn site +``` Jetty peut être utilisé pour le rendu en temps réel, c'est-à -dire qu'il suffit de rafraîchir le navigateur pour afficher @@ -52,9 +58,3 @@ généralement http://localhost:8080/. Au besoin, regénérer les diagrammes UML avec la commande `mvn com.github.jeluard:plantuml-maven-plugin:generate`. - -Les fichiers Markdown listant les indicateurs sont générés par la classe `Knowlegde` que l'on peut exécuter avec Maven : -`mvn exec:java -Dexec.mainClass="fr.inrae.agroclim.indicators.model.Knowledge"`. ----- - -`$Id$` diff --git a/src/site/site.xml b/src/site/site.xml index 3059eae5..f0bb9bd0 100644 --- a/src/site/site.xml +++ b/src/site/site.xml @@ -26,6 +26,10 @@ <body> <menu name="Documentation" inherit="top"> <item name="Accueil" href="index.html" /> + <item name="Indicateurs horaires" href="indicators-hourly-fr.html" /> + <item name="Indicateurs journaliers" href="indicators-daily-fr.html" /> + <item name="Codes d'erreurs" href="errors-fr.html" /> + <item name="Documentation in English" href="en/index.html" /> </menu> <menu ref="modules" inherit="top" /> <menu ref="reports" inherit="top" /> diff --git a/src/site/site_en.xml b/src/site/site_en.xml new file mode 100644 index 00000000..ce0af405 --- /dev/null +++ b/src/site/site_en.xml @@ -0,0 +1,38 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE xml> +<!-- Last changed : $Date$ --> +<!-- @author $Author$ --> +<!-- @version $Revision$ --> +<project name="${project.name}"> + <skin> + <groupId>org.apache.maven.skins</groupId> + <artifactId>maven-fluido-skin</artifactId> + <version>1.9</version> + </skin> + + <custom> + <fluidoSkin> + <sideBarEnabled>true</sideBarEnabled> + <sourceLineNumbersEnabled>true</sourceLineNumbersEnabled> + </fluidoSkin> + </custom> + + <bannerLeft> + <name>Documentation for ${project.name}</name> + </bannerLeft> + + <version position="bottom" /> + + <body> + <menu name="Documentation" inherit="top"> + <item name="Home" href="index.html" /> + <item name="Hourly indicators" href="indicators-hourly-en.html" /> + <item name="Daily indicators" href="indicators-daily-en.html" /> + <item name="Error codes" href="errors-en.html" /> + <item name="Documentation en français" href="../index.html" /> + </menu> + <menu ref="modules" inherit="top" /> + <menu ref="reports" inherit="top" /> + <menu ref="parent" inherit="top" /> + </body> +</project> \ No newline at end of file diff --git a/src/test/java/fr/inrae/agroclim/indicators/exception/IndicatorsErrorCategoryTest.java b/src/test/java/fr/inrae/agroclim/indicators/exception/IndicatorsErrorCategoryTest.java new file mode 100644 index 00000000..25ea12db --- /dev/null +++ b/src/test/java/fr/inrae/agroclim/indicators/exception/IndicatorsErrorCategoryTest.java @@ -0,0 +1,60 @@ +package fr.inrae.agroclim.indicators.exception; + +import fr.inrae.agroclim.indicators.resources.I18n; +import java.util.Arrays; +import java.util.List; +import java.util.Locale; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.Test; +import static org.junit.Assert.assertFalse; + +/** + * Ensure all translations of {@link IndicatorsErrorCategory} are well defined. + * + * @author Olivier Maury + */ +@RunWith(Parameterized.class) +public class IndicatorsErrorCategoryTest { + + /** + * @return classes to test. + */ + @Parameterized.Parameters + public static List<IndicatorsErrorCategory> data() { + return Arrays.asList(IndicatorsErrorCategory.values()); + } + + /** + * Category to test. + */ + private final IndicatorsErrorCategory category; + + /** + * Constructor. + * + * @param cat category to test + */ + public IndicatorsErrorCategoryTest(final IndicatorsErrorCategory cat) { + this.category = cat; + } + + private void missingTranslation(Locale locale) { + final String bundleName = "fr.inrae.agroclim.indicators.resources.messages"; + final I18n i18n = new I18n(bundleName, locale); + final String tr = category.getCategory(i18n); + final boolean actual = tr.startsWith("!") && tr.endsWith("!"); + final String msg = tr + " is not translated in " + locale; + assertFalse(msg, actual); + } + + @Test + public void missingTranslationEnglish() { + missingTranslation(Locale.ENGLISH); + } + + @Test + public void missingTranslationFrench() { + missingTranslation(Locale.FRENCH); + } +} -- GitLab From 825f0261f2979dd2c23653fd6e1734a2b5fb2468 Mon Sep 17 00:00:00 2001 From: Olivier Maury <Olivier.Maury@inrae.fr> Date: Thu, 4 Jan 2024 12:30:05 +0100 Subject: [PATCH 11/20] Test GitLab pages --- .gitlab-ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 61201565..45bc65be 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -69,7 +69,9 @@ deploy_job: pages_job: stage: deploy + needs: ["package_job"] script: + - mvn --version - mvn exec:java -Dexec.mainClass=fr.inrae.agroclim.indicators.GenerateMarkdown -Dexec.args='${basedir}/src/site/markdown -' - mv src/site/markdown/*-en.md src/site/en/markdown/ - mvn site @@ -77,5 +79,3 @@ pages_job: artifacts: paths: - public - only: - - tags -- GitLab From 2a20e1c7ebb894d5fdc7967fb8a019213563d213 Mon Sep 17 00:00:00 2001 From: Olivier Maury <Olivier.Maury@inrae.fr> Date: Thu, 4 Jan 2024 14:08:47 +0100 Subject: [PATCH 12/20] Test GitLab pages --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 45bc65be..7806ab01 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -72,7 +72,7 @@ pages_job: needs: ["package_job"] script: - mvn --version - - mvn exec:java -Dexec.mainClass=fr.inrae.agroclim.indicators.GenerateMarkdown -Dexec.args='${basedir}/src/site/markdown -' + - mvn compile exec:java -DskipTests -Dexec.mainClass=fr.inrae.agroclim.indicators.GenerateMarkdown -Dexec.args='${basedir}/src/site/markdown -' - mv src/site/markdown/*-en.md src/site/en/markdown/ - mvn site - mv target/site public -- GitLab From cdbe559ad8284b22c52f9811945530991226f703 Mon Sep 17 00:00:00 2001 From: Olivier Maury <Olivier.Maury@inrae.fr> Date: Thu, 4 Jan 2024 14:33:17 +0100 Subject: [PATCH 13/20] Correction CI pour Pages --- .gitlab-ci.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 7806ab01..23a11b0c 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -71,11 +71,12 @@ pages_job: stage: deploy needs: ["package_job"] script: - - mvn --version - mvn compile exec:java -DskipTests -Dexec.mainClass=fr.inrae.agroclim.indicators.GenerateMarkdown -Dexec.args='${basedir}/src/site/markdown -' - mv src/site/markdown/*-en.md src/site/en/markdown/ - mvn site - - mv target/site public artifacts: paths: - - public + - target/site + publish: target/site + only: + - tags -- GitLab From 1c16abe87d6aa0eed4700737ac1f389a196a3fec Mon Sep 17 00:00:00 2001 From: Olivier Maury <olivier.maury@inrae.fr> Date: Thu, 4 Jan 2024 14:36:27 +0100 Subject: [PATCH 14/20] =?UTF-8?q?Mettre=20=C3=A0=20jour=20le=20fichier=20.?= =?UTF-8?q?gitlab-ci.yml?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitlab-ci.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 23a11b0c..ac6abfca 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -9,7 +9,6 @@ stages: - code-check - package - deploy - - pages cache: paths: @@ -67,7 +66,7 @@ deploy_job: script: - echo "Maven deploy started" -pages_job: +pages: stage: deploy needs: ["package_job"] script: -- GitLab From 4b81cdac97a6ec6a5adbe615d164ca86e987285e Mon Sep 17 00:00:00 2001 From: Olivier Maury <Olivier.Maury@inrae.fr> Date: Thu, 4 Jan 2024 15:33:54 +0100 Subject: [PATCH 15/20] CI : JaCoCo -> Cobertura --- .gitlab-ci.yml | 15 ++++++++++++--- pom.xml | 8 ++++++++ .../exception/type/CommonErrorType.java | 2 +- 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index ac6abfca..d73e5273 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -13,12 +13,13 @@ stages: cache: paths: - .m2/repository + - target build_job: stage: build script: - echo "Maven compile started" - - mvn compile test-compile + - mvn clean compile test-compile - ls -lha /usr/bin/tokei - /usr/bin/tokei --version @@ -53,6 +54,14 @@ cpd_job: script: - mvn pmd:cpd +cobertura_job: + stage: deploy + image: registry.gitlab.com/haynes/jacoco2cobertura:1.0.7 + needs: ["test_job"] + script: + # convert report from jacoco to cobertura, using relative project path + - python /opt/cover2cover.py target/site/jacoco/jacoco.xml $CI_PROJECT_DIR/src/main/java/ > target/cobertura.xml + package_job: stage: package script: @@ -70,9 +79,9 @@ pages: stage: deploy needs: ["package_job"] script: - - mvn compile exec:java -DskipTests -Dexec.mainClass=fr.inrae.agroclim.indicators.GenerateMarkdown -Dexec.args='${basedir}/src/site/markdown -' + - mvn exec:java -DskipTests -Dexec.mainClass=fr.inrae.agroclim.indicators.GenerateMarkdown -Dexec.args='${basedir}/src/site/markdown -' - mv src/site/markdown/*-en.md src/site/en/markdown/ - - mvn site + - mvn site -DskipTests artifacts: paths: - target/site diff --git a/pom.xml b/pom.xml index fe9f90b4..4c04a362 100644 --- a/pom.xml +++ b/pom.xml @@ -287,6 +287,14 @@ along with Indicators. If not, see <https://www.gnu.org/licenses/>. <goal>report</goal> </goals> </execution> + <execution> + <!-- Generate coverage report XML in target/site/jacoco/ from target/jacoco.exec --> + <id>report-test</id> + <phase>test</phase> + <goals> + <goal>report</goal> + </goals> + </execution> <execution> <!-- Generate coverage report html in target/site/jacoco/ from target/jacoco.exec --> <id>report</id> diff --git a/src/main/java/fr/inrae/agroclim/indicators/exception/type/CommonErrorType.java b/src/main/java/fr/inrae/agroclim/indicators/exception/type/CommonErrorType.java index 8db6e449..5d936c0b 100644 --- a/src/main/java/fr/inrae/agroclim/indicators/exception/type/CommonErrorType.java +++ b/src/main/java/fr/inrae/agroclim/indicators/exception/type/CommonErrorType.java @@ -22,7 +22,7 @@ public interface CommonErrorType extends ErrorType { CommonErrorType getParent(); /** - * @return error name (as {@link Enum#name()). + * @return error name (as {@link Enum#name()}). */ String name(); -- GitLab From 03e89abbd4c128275a7cba53e7de81231bc2ad72 Mon Sep 17 00:00:00 2001 From: Olivier Maury <Olivier.Maury@inrae.fr> Date: Thu, 4 Jan 2024 15:38:17 +0100 Subject: [PATCH 16/20] CI : JaCoCo -> Cobertura --- .gitlab-ci.yml | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index d73e5273..00847c49 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -13,7 +13,6 @@ stages: cache: paths: - .m2/repository - - target build_job: stage: build @@ -22,6 +21,9 @@ build_job: - mvn clean compile test-compile - ls -lha /usr/bin/tokei - /usr/bin/tokei --version + artifacts: + paths: + - target test_job: stage: test @@ -31,6 +33,8 @@ test_job: - mvn test artifacts: when: always + paths: + - target reports: junit: - target/surefire-reports/TEST-*.xml @@ -41,18 +45,27 @@ checkstyle_job: needs: ["build_job"] script: - mvn checkstyle:checkstyle + artifacts: + paths: + - target pmd_job: stage: code-check needs: ["build_job"] script: - mvn pmd:pmd + artifacts: + paths: + - target cpd_job: stage: code-check needs: ["build_job"] script: - mvn pmd:cpd + artifacts: + paths: + - target cobertura_job: stage: deploy @@ -61,12 +74,18 @@ cobertura_job: script: # convert report from jacoco to cobertura, using relative project path - python /opt/cover2cover.py target/site/jacoco/jacoco.xml $CI_PROJECT_DIR/src/main/java/ > target/cobertura.xml + artifacts: + paths: + - target package_job: stage: package script: - echo "Maven packaging started" - mvn package -DskipTests + artifacts: + paths: + - target deploy_job: stage: deploy -- GitLab From 3d5363fe151c58a0bad0bced40109c7b2c556b01 Mon Sep 17 00:00:00 2001 From: Olivier Maury <Olivier.Maury@inrae.fr> Date: Thu, 4 Jan 2024 15:52:12 +0100 Subject: [PATCH 17/20] CI : JaCoCo -> Cobertura, ne pas utiliser d'image externe --- .gitlab-ci.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 00847c49..37ac49db 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -69,7 +69,6 @@ cpd_job: cobertura_job: stage: deploy - image: registry.gitlab.com/haynes/jacoco2cobertura:1.0.7 needs: ["test_job"] script: # convert report from jacoco to cobertura, using relative project path -- GitLab From 675307d6df53c1f7f8068e2513789f2f9fd100fe Mon Sep 17 00:00:00 2001 From: Olivier Maury <Olivier.Maury@inrae.fr> Date: Thu, 4 Jan 2024 18:30:57 +0100 Subject: [PATCH 18/20] Corrections mineures pour SEASON --- pom.xml | 6 ++++ .../indicators/exception/ErrorMessage.java | 36 ++++++++----------- .../exception/IndicatorsException.java | 16 ++++----- src/main/java/module-info.java | 1 + .../exception/ErrorMessageTest.java | 6 +++- .../exception/IndicatorsExceptionTest.java | 21 +++++++++++ 6 files changed, 56 insertions(+), 30 deletions(-) create mode 100644 src/test/java/fr/inrae/agroclim/indicators/exception/IndicatorsExceptionTest.java diff --git a/pom.xml b/pom.xml index 4c04a362..554c8af1 100644 --- a/pom.xml +++ b/pom.xml @@ -148,6 +148,12 @@ along with Indicators. If not, see <https://www.gnu.org/licenses/>. <artifactId>jackson-dataformat-csv</artifactId> <version>2.15.2</version> </dependency> + <!-- JSON for error output --> + <dependency> + <groupId>org.json</groupId> + <artifactId>json</artifactId> + <version>20190722</version> + </dependency> <!-- JEXL --> <dependency> <groupId>org.apache.commons</groupId> diff --git a/src/main/java/fr/inrae/agroclim/indicators/exception/ErrorMessage.java b/src/main/java/fr/inrae/agroclim/indicators/exception/ErrorMessage.java index bcf2e83b..674639f3 100644 --- a/src/main/java/fr/inrae/agroclim/indicators/exception/ErrorMessage.java +++ b/src/main/java/fr/inrae/agroclim/indicators/exception/ErrorMessage.java @@ -25,6 +25,7 @@ import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.RequiredArgsConstructor; import lombok.ToString; +import org.json.JSONObject; /** * Error messages for the user. @@ -115,28 +116,21 @@ public final class ErrorMessage implements Serializable { * @return JSON representation */ public String toJSON() { - final StringBuilder sb = new StringBuilder(); - sb.append("{"); - sb.append("\"bundleName\": \"").append(bundleName).append("\", "); - sb.append("\"errorCode\": \"").append(type.getFullCode()).append("\", "); - sb.append("\"errorName\": \"").append(type.getName()).append("\", "); - sb.append("\"arguments\": ["); + final JSONObject json = new JSONObject(); + json.put("bundleName", bundleName); + if (type.getCategory() != null) { + final JSONObject cat = new JSONObject(); + cat.put("code", type.getCategory().getCode()); + cat.put("name", type.getCategory().getName()); + json.put("category", cat); + } + final JSONObject error = new JSONObject(); + error.put("code", type.getFullCode()); + error.put("name", type.getName()); + json.put("error", error); if (arguments != null) { - boolean first = true; - for (final Object arg : arguments) { - if (first) { - first = false; - } else { - sb.append(", "); - } - sb.append("\"") - .append(arg.toString() - .replace("\"", "\\\"") - .replace("'", "\\'")) - .append("\""); - } + json.put("arguments", arguments.stream().map(Object::toString).toList()); } - sb.append("]}"); - return sb.toString(); + return json.toString(2); } } diff --git a/src/main/java/fr/inrae/agroclim/indicators/exception/IndicatorsException.java b/src/main/java/fr/inrae/agroclim/indicators/exception/IndicatorsException.java index bef29720..d6f4bf2a 100644 --- a/src/main/java/fr/inrae/agroclim/indicators/exception/IndicatorsException.java +++ b/src/main/java/fr/inrae/agroclim/indicators/exception/IndicatorsException.java @@ -6,12 +6,13 @@ import java.util.List; /** * An exception with {@link ErrorMessage} to describe the error in the Indicators library to the user. * - * Last changed : $Date: 2023-03-16 17:39:08 +0100 (jeu. 16 mars 2023) $ - * - * @author $Author: omaury $ - * @version $Revision: 1247 $ + * @author Olivier Maury */ -public class IndicatorsException extends ErrorMessageException { +public class IndicatorsException extends ErrorMessageException { + /** + * Path of .property resource. + */ + private static final String BUNDLE_NAME = "fr.inrae.agroclim.indicators.resources.messages"; /** * UUID for Serializable. @@ -25,7 +26,7 @@ public class IndicatorsException extends ErrorMessageException { * @param arguments Arguments for the message. */ public IndicatorsException(final ErrorType errorType, final Serializable... arguments) { - super(new ErrorMessage("fr.inrae.agroclim.indicators.resources.messages", errorType, List.of(arguments))); + super(new ErrorMessage(BUNDLE_NAME, errorType, List.of(arguments))); } /** @@ -39,7 +40,6 @@ public class IndicatorsException extends ErrorMessageException { * unknown.) */ public IndicatorsException(final ErrorType errorType, final Throwable cause, final Serializable... arguments) { - super(new ErrorMessage("fr.inrae.agroclim.indicators.resources.messages", errorType, List.of(arguments)), - cause); + super(new ErrorMessage(BUNDLE_NAME, errorType, List.of(arguments)), cause); } } diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java index 88e38656..d3f3036b 100644 --- a/src/main/java/module-info.java +++ b/src/main/java/module-info.java @@ -30,6 +30,7 @@ module fr.inrae.agroclim.indicators { requires transitive java.desktop; requires org.apache.logging.log4j; requires org.apache.logging.log4j.core; + requires org.json; exports fr.inrae.agroclim.indicators.exception; exports fr.inrae.agroclim.indicators.model; diff --git a/src/test/java/fr/inrae/agroclim/indicators/exception/ErrorMessageTest.java b/src/test/java/fr/inrae/agroclim/indicators/exception/ErrorMessageTest.java index 9d8cbcaa..a6324951 100644 --- a/src/test/java/fr/inrae/agroclim/indicators/exception/ErrorMessageTest.java +++ b/src/test/java/fr/inrae/agroclim/indicators/exception/ErrorMessageTest.java @@ -17,6 +17,8 @@ package fr.inrae.agroclim.indicators.exception; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; import java.io.Serializable; import java.util.Arrays; @@ -95,7 +97,6 @@ public class ErrorMessageTest { */ @Test public void getMessageWithArguments() { - final ErrorI18nKey key = ErrorI18nKey.KEY; final String category = "climate"; final Integer line = 11; @@ -109,6 +110,9 @@ public class ErrorMessageTest { expected = defaultResources.format(key.getI18nKey(), category, line); found = error.getMessage(); assertEquals(expected, found); + + assertNotNull(error.toJSON()); + assertFalse(error.toJSON().isBlank()); } /** diff --git a/src/test/java/fr/inrae/agroclim/indicators/exception/IndicatorsExceptionTest.java b/src/test/java/fr/inrae/agroclim/indicators/exception/IndicatorsExceptionTest.java new file mode 100644 index 00000000..72fdf172 --- /dev/null +++ b/src/test/java/fr/inrae/agroclim/indicators/exception/IndicatorsExceptionTest.java @@ -0,0 +1,21 @@ +package fr.inrae.agroclim.indicators.exception; + +import fr.inrae.agroclim.indicators.exception.type.ComputationErrorType; +import static org.junit.Assert.assertEquals; +import org.junit.Test; + +/** + * Test translations and formatting of exception message. + * + * @author Olivier Maury + */ +public class IndicatorsExceptionTest { + + @Test + public void getLocalizedMessage() { + var instance = new IndicatorsException(ComputationErrorType.FORMULA, "m * c * c"); + var actual = instance.getLocalizedMessage(); + var expected = "Error while executing expression \"m * c * c\"."; + assertEquals(expected, actual); + } +} -- GitLab From 06a41f4011d2b8b40f45eb37994ecb0f02542bff Mon Sep 17 00:00:00 2001 From: Olivier Maury <Olivier.Maury@inrae.fr> Date: Fri, 5 Jan 2024 08:06:46 +0100 Subject: [PATCH 19/20] Fixer la locale pour le test. --- .../agroclim/indicators/exception/IndicatorsExceptionTest.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/test/java/fr/inrae/agroclim/indicators/exception/IndicatorsExceptionTest.java b/src/test/java/fr/inrae/agroclim/indicators/exception/IndicatorsExceptionTest.java index 72fdf172..63988bc0 100644 --- a/src/test/java/fr/inrae/agroclim/indicators/exception/IndicatorsExceptionTest.java +++ b/src/test/java/fr/inrae/agroclim/indicators/exception/IndicatorsExceptionTest.java @@ -1,6 +1,7 @@ package fr.inrae.agroclim.indicators.exception; import fr.inrae.agroclim.indicators.exception.type.ComputationErrorType; +import java.util.Locale; import static org.junit.Assert.assertEquals; import org.junit.Test; @@ -13,6 +14,7 @@ public class IndicatorsExceptionTest { @Test public void getLocalizedMessage() { + Locale.setDefault(Locale.ENGLISH); var instance = new IndicatorsException(ComputationErrorType.FORMULA, "m * c * c"); var actual = instance.getLocalizedMessage(); var expected = "Error while executing expression \"m * c * c\"."; -- GitLab From c12056d99fa85cd5976ae06f7862e3419913efa1 Mon Sep 17 00:00:00 2001 From: Olivier Maury <Olivier.Maury@inrae.fr> Date: Fri, 5 Jan 2024 10:02:11 +0100 Subject: [PATCH 20/20] =?UTF-8?q?Suppression=20d'exceptions=20non=20utilis?= =?UTF-8?q?=C3=A9es?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 2 +- .../exception/AbstractException.java | 59 ------------------- .../exception/FunctionalException.java | 48 --------------- .../exception/TechnicalException.java | 46 --------------- 4 files changed, 1 insertion(+), 154 deletions(-) delete mode 100644 src/main/java/fr/inrae/agroclim/indicators/exception/AbstractException.java delete mode 100644 src/main/java/fr/inrae/agroclim/indicators/exception/FunctionalException.java delete mode 100644 src/main/java/fr/inrae/agroclim/indicators/exception/TechnicalException.java diff --git a/pom.xml b/pom.xml index 554c8af1..e8fcf487 100644 --- a/pom.xml +++ b/pom.xml @@ -22,7 +22,7 @@ along with Indicators. If not, see <https://www.gnu.org/licenses/>. <name>Indicators</name> <description>Library of agro- and eco-climatic indicators.</description> <inceptionYear>2018</inceptionYear> - <version>1.3.0-SNAPSHOT</version> + <version>2.0.0-SNAPSHOT</version> <packaging>jar</packaging> <licenses> <license> diff --git a/src/main/java/fr/inrae/agroclim/indicators/exception/AbstractException.java b/src/main/java/fr/inrae/agroclim/indicators/exception/AbstractException.java deleted file mode 100644 index 86b51eb9..00000000 --- a/src/main/java/fr/inrae/agroclim/indicators/exception/AbstractException.java +++ /dev/null @@ -1,59 +0,0 @@ -/** - * This file is part of Indicators. - * - * Indicators is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Indicators is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Indicators. If not, see <https://www.gnu.org/licenses/>. - */ -package fr.inrae.agroclim.indicators.exception; - -/** - * Base class for FunctionalException and TechnicalException. - */ -public abstract class AbstractException extends Exception { - /** - * UUID for Serializable. - */ - private static final long serialVersionUID = 6030595237342400001L; - - /** - * Root exception. - */ - private final Exception rootException; - - /** - * @param msg - * exception message - */ - protected AbstractException(final String msg) { - super(msg); - rootException = null; - } - - /** - * @param msg - * exception message - * @param e - * root exception - */ - protected AbstractException(final String msg, final Exception e) { - super(msg); - this.rootException = e; - } - - /** - * @return Root exception. - */ - public final Exception getRootException() { - return rootException; - } -} diff --git a/src/main/java/fr/inrae/agroclim/indicators/exception/FunctionalException.java b/src/main/java/fr/inrae/agroclim/indicators/exception/FunctionalException.java deleted file mode 100644 index 831c2c77..00000000 --- a/src/main/java/fr/inrae/agroclim/indicators/exception/FunctionalException.java +++ /dev/null @@ -1,48 +0,0 @@ -/** - * This file is part of Indicators. - * - * Indicators is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Indicators is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Indicators. If not, see <https://www.gnu.org/licenses/>. - */ -package fr.inrae.agroclim.indicators.exception; - -/** - * For Indicator, Evaluation and AggregationFunction. - * - * @deprecated Use {@link IndicatorsException}. - */ -@Deprecated -public class FunctionalException extends AbstractException { - /** - * UUID for Serializable. - */ - private static final long serialVersionUID = 6030595237342400002L; - - /** - * @param msg - * exception message - */ - public FunctionalException(final String msg) { - super(msg); - } - - /** - * @param msg - * exception message - * @param e - * root exception - */ - public FunctionalException(final String msg, final Exception e) { - super(msg, e); - } -} diff --git a/src/main/java/fr/inrae/agroclim/indicators/exception/TechnicalException.java b/src/main/java/fr/inrae/agroclim/indicators/exception/TechnicalException.java deleted file mode 100644 index ecee955e..00000000 --- a/src/main/java/fr/inrae/agroclim/indicators/exception/TechnicalException.java +++ /dev/null @@ -1,46 +0,0 @@ -/** - * This file is part of Indicators. - * - * Indicators is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Indicators is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Indicators. If not, see <https://www.gnu.org/licenses/>. - */ -package fr.inrae.agroclim.indicators.exception; - -/** - * For XMLUtils. - * - * @deprecated Use {@link IndicatorsException}. - */ -@Deprecated -public class TechnicalException extends AbstractException { - - /** - * UUID for Serializable. - */ - private static final long serialVersionUID = 6030595237342400003L; - - /** - * @param msg exception message - */ - public TechnicalException(final String msg) { - super(msg); - } - - /** - * @param msg exception message - * @param e root exception - */ - public TechnicalException(final String msg, final Exception e) { - super(msg, e); - } -} -- GitLab