VariableCriteria.java

/*
 * Copyright (C) 2020 INRAE AgroClim
 *
 * 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 <http://www.gnu.org/licenses/>.
 */
package fr.inrae.agroclim.indicators.model.criteria;

import java.util.Objects;
import java.util.Set;

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 fr.inrae.agroclim.indicators.model.data.Variable;
import jakarta.xml.bind.annotation.XmlAccessType;
import jakarta.xml.bind.annotation.XmlAccessorType;
import jakarta.xml.bind.annotation.XmlElement;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;

/**
 * Criteria on one variable.
 *
 * Last changed : $Date$
 *
 * @author omaury
 * @author $Author$
 * @version $Revision$
 */
@EqualsAndHashCode(
        callSuper = true,
        of = {"variable"}
        )
@XmlAccessorType(XmlAccessType.FIELD)
public abstract class VariableCriteria extends Criteria {
    /**
     * UUID for Serializable.
     */
    private static final long serialVersionUID = -4284278102762199666L;

    /**
     * Variable name (property of ClimaticDailyData).
     */
    @XmlElement(name = "variable", required = true)
    @Getter
    @Setter
    private Variable variable;

    /**
     * Retourne la valeur de l'attribut nommée "variable" de l'objet de type
     * daily data.
     *
     * @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) throws IndicatorsException {
        if (data == null) {
            throw new IndicatorsException(ComputationErrorType.DATA_NULL);
        }
        if (variable == null) {
            throw new IndicatorsException(ComputationErrorType.VARIABLE_NAME_NULL);
        }
        final var value = data.getValue(variable);
        if (value == null) {
            throw new IndicatorsException(ComputationErrorType.VARIABLE_VALUE_NULL, data.getDate(), variable);
        }
        return value;
    }

    @Override
    public final Set<Variable> getVariables() {
        return Set.of(variable);
    }

    /**
     * @param res ClimaticResource
     * @return climaticResource contains "variable"
     */
    @Override
    public final boolean isComputable(final Resource<? extends DailyData> res) {
        Objects.requireNonNull(getVariable(),
                "Variable must be set for " + getClass().getCanonicalName());
        return !res.getMissingVariables().contains(getVariable().getName());
    }
}