SimpleIndicatorWithCriteria.java
/*
* 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.model.indicator;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import fr.inrae.agroclim.indicators.model.Knowledge;
import fr.inrae.agroclim.indicators.model.Parameter;
import fr.inrae.agroclim.indicators.model.criteria.Criteria;
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 fr.inrae.agroclim.indicators.model.function.normalization.NormalizationFunction;
import fr.inrae.agroclim.indicators.model.indicator.listener.IndicatorEvent;
import fr.inrae.agroclim.indicators.util.Doublet;
import jakarta.xml.bind.Unmarshaller;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.extern.log4j.Log4j2;
/**
* A simple indicator with a criteria.
*
* Last change $Date$
*
* @author $Author$
* @version $Revision$
*/
@EqualsAndHashCode(
callSuper = true,
of = {"criteria"}
)
@Log4j2
public abstract class SimpleIndicatorWithCriteria extends SimpleIndicator implements PropertyChangeListener {
/**
* UUID for Serializable.
*/
private static final long serialVersionUID = 6030595237342422016L;
/**
* Criteria.
*/
@Getter
private Criteria criteria;
/**
* Constructor.
*/
protected SimpleIndicatorWithCriteria() {
super();
}
/**
* Constructor with function.
*
* @param n function to normalize value
*/
protected SimpleIndicatorWithCriteria(final NormalizationFunction n) {
super(n);
}
/**
* Called after all the properties (except IDREF) are unmarshalled for this
* object, but before this object is set to the parent object.
*
* @param u JAXB unmarshaller
* @param parent instance of JAXB mapped class that will reference target.
* null when target is root element.
*/
final void afterUnmarshal(final Unmarshaller u, final Object parent) {
if (this.getCriteria() != null) {
this.getCriteria().addPropertyChangeListener(this);
}
}
@Override
@SuppressWarnings("checkstyle:DesignForExtension")
public SimpleIndicatorWithCriteria clone()
throws CloneNotSupportedException {
SimpleIndicatorWithCriteria clone;
clone = (SimpleIndicatorWithCriteria) super.clone();
if (criteria != null) {
clone.criteria = getCriteria().clone();
clone.criteria.addPropertyChangeListener(clone);
}
return clone;
}
/**
* Get the defaults from the criteria.
*
* @return parameter for substituted attribute ⮕ value of attribute from the evaluation. Must not be null.
*/
@Override
public List<Doublet<Parameter, Number>> getParameterDefaults() {
return getCriteria().getParameterDefaults();
}
@Override
public final List<Parameter> getParameters() {
final List<Parameter> params = new ArrayList<>();
if (super.getParameters() != null) {
params.addAll(super.getParameters());
}
Objects.requireNonNull(getCriteria(), "Criteria must not be null in " + getId());
if (getCriteria().getParameters() != null) {
getCriteria().getParameters().forEach(param -> {
if (!params.contains(param)) {
params.add(param);
}
});
}
return params;
}
@Override
public final Map<String, Double> getParametersValues() {
return getCriteria().getParametersValues();
}
@Override
public final Set<Variable> getVariables() {
Objects.requireNonNull(getCriteria(), "Criteria should not be null for " + getName());
return getCriteria().getVariables();
}
@Override
public final boolean isComputable(final Resource<? extends DailyData> res) {
return getCriteria().isComputable(res);
}
@Override
public final void propertyChange(final PropertyChangeEvent pce) {
LOGGER.traceEntry();
fireIndicatorEvent(IndicatorEvent.Type.CHANGE.event(this));
}
/**
* @param c criteria
*/
public final void setCriteria(final Criteria c) {
this.criteria = c;
if (this.getCriteria() != null) {
this.getCriteria().addPropertyChangeListener(this);
}
}
@Override
public final void setParametersFromKnowledge(final Knowledge knowledge) {
LOGGER.traceEntry();
if (getCriteria() == null) {
return;
}
SimpleIndicatorWithCriteria indicator = (SimpleIndicatorWithCriteria) knowledge.getIndicator(getId());
if (indicator == null) {
return;
}
final List<Parameter> values = indicator.getCriteria().getParameters();
if (values != null && !values.isEmpty()) {
getCriteria().setParameters(values);
}
LOGGER.traceExit();
}
@Override
public final void setParametersValues(final Map<String, Double> values) {
getCriteria().setParametersValues(values);
}
/**
* To override, use super or use toStringTreeBase() and also getCriteria().toStringTree(indent + " ").
*
* @param indent intent of tree representation
* @return tree representation
*/
@Override
public String toStringTree(final String indent) {
final StringBuilder sb = new StringBuilder();
sb.append(toStringTreeBase(indent));
if (getCriteria() != null) {
sb.append(indent).append(" criteria:\n")
.append(getCriteria().toStringTree(indent + " "))
.append("\n");
}
return sb.toString();
}
@Override
public final void removeParameter(final Parameter param) {
if (getCriteria() != null) {
this.getCriteria().removeParameter(param);
}
if (super.getParameters() != null) {
super.getParameters().remove(param);
}
}
}