/* * Copyright (c) 2017 OBiBa. All rights reserved. * * This program and the accompanying materials * are made available under the terms of the GNU Public License v3.0. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.obiba.magma.datasource.generated; import java.util.List; import javax.validation.constraints.NotNull; import org.obiba.magma.AbstractVariableValueSource; import org.obiba.magma.Value; import org.obiba.magma.ValueSet; import org.obiba.magma.ValueSource; import org.obiba.magma.ValueType; import org.obiba.magma.Variable; import org.obiba.magma.VariableValueSource; import org.obiba.magma.VectorSource; import org.obiba.magma.VectorSourceNotSupportedException; import org.obiba.magma.js.JavascriptValueSource; import org.obiba.magma.support.Initialisables; import org.obiba.magma.type.BooleanType; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.common.collect.Lists; abstract class GeneratedVariableValueSource extends AbstractVariableValueSource implements VariableValueSource { private final static Logger log = LoggerFactory.getLogger(GeneratedVariableValueSource.class); private final Variable variable; private final ValueSource condition; protected GeneratedVariableValueSource(Variable variable) { this.variable = variable; if(variable.hasAttribute("condition")) { JavascriptValueSource src = new JavascriptValueSource(BooleanType.get(), variable.getAttributeStringValue("condition")); try { Initialisables.initialise(src); } catch(RuntimeException e) { log.warn("Cannot compile condition for variable {}", variable.getName()); //noinspection AssignmentToNull src = null; } condition = src; } else { condition = null; } } @NotNull @Override public Variable getVariable() { return variable; } @Override public boolean supportVectorSource() { return false; } @NotNull @Override public VectorSource asVectorSource() { throw new VectorSourceNotSupportedException(getClass()); } @NotNull @Override public Value getValue(ValueSet valueSet) { if(shouldGenerate(valueSet)) { GeneratedValueSet gvs = (GeneratedValueSet) valueSet; try { Value existingValue = gvs.getExistingValue(getVariable().getName()); if(existingValue != null) { return existingValue; } if(variable.isRepeatable()) { int sequenceLength = gvs.dataGenerator.nextInt(0, 10); List<Value> values = Lists.newArrayListWithCapacity(sequenceLength); for(int i = 0; i < sequenceLength; i++) { values.add(nextValue(getVariable(), gvs)); } return gvs.put(getVariable().getName(), ValueType.Factory.newSequence(variable.getValueType(), values)); } return gvs.put(getVariable().getName(), nextValue(getVariable(), gvs)); } catch(RuntimeException e) { //noinspection StringConcatenationArgumentToLogCall log.warn("Error generating data for variable " + getVariable().getName(), e); return getValueType().nullValue(); } } return getValueType().nullValue(); } @NotNull @Override public ValueType getValueType() { return getVariable().getValueType(); } protected boolean shouldGenerate(ValueSet valueSet) { if(condition != null) { try { Value value = condition.getValue(valueSet); return value.isNull() ? false : (Boolean) value.getValue(); } catch(RuntimeException e) { log.warn("Error evaluating condition for variable {}", getVariable().getName()); } } return true; } abstract protected Value nextValue(Variable variable, GeneratedValueSet gvs); }