/* * Copyright (C) 2006-2016 DLR, Germany * * All rights reserved * * http://www.rcenvironment.de/ */ package de.rcenvironment.components.doe.execution.validator; import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; import org.codehaus.jackson.map.ObjectMapper; import de.rcenvironment.components.doe.common.DOEAlgorithms; import de.rcenvironment.components.doe.common.DOEConstants; import de.rcenvironment.components.doe.execution.Messages; import de.rcenvironment.core.component.api.LoopComponentConstants; import de.rcenvironment.core.component.model.api.ComponentDescription; import de.rcenvironment.core.component.model.endpoint.api.EndpointDescription; import de.rcenvironment.core.component.validation.api.ComponentValidationMessage; import de.rcenvironment.core.component.validation.spi.AbstractLoopComponentValidator; import de.rcenvironment.core.utils.common.JsonUtils; /** * Validator for DOE component. * * @author Sascha Zur * @author Jascha Riedel */ public class DOEComponentValidator extends AbstractLoopComponentValidator { @Override public String getIdentifier() { return DOEConstants.COMPONENT_ID; } @Override protected List<ComponentValidationMessage> validateLoopComponentSpecific( ComponentDescription componentDescription) { List<ComponentValidationMessage> messages = new ArrayList<>(); final boolean hasOutputs = getOutputs(componentDescription).size() > 0; if (!hasOutputs) { final ComponentValidationMessage noInputMessage = new ComponentValidationMessage( ComponentValidationMessage.Type.ERROR, "", Messages.noOutputsDefinedLong, Messages.noOutputsDefinedLong); messages.add(noInputMessage); } else { int outputCount = getOutputs(componentDescription).size(); int runNumber = Integer.parseInt(getProperty(componentDescription, DOEConstants.KEY_RUN_NUMBER)); final ComponentValidationMessage tooManySamplesMessage = new ComponentValidationMessage( ComponentValidationMessage.Type.ERROR, "", Messages.tooManySamples, Messages.tooManySamples); if (getProperty(componentDescription, DOEConstants.KEY_METHOD) .equals(DOEConstants.DOE_ALGORITHM_FULLFACT)) { if (Math.pow(runNumber, outputCount) >= DOEAlgorithms.MAXMIMAL_RUNS) { messages.add(tooManySamplesMessage); } } else { if (runNumber >= DOEAlgorithms.MAXMIMAL_RUNS) { messages.add(tooManySamplesMessage); } } } if (!(getProperty(componentDescription, DOEConstants.KEY_METHOD).equals(DOEConstants.DOE_ALGORITHM_CUSTOM_TABLE) || getProperty(componentDescription, DOEConstants.KEY_METHOD) .equals(DOEConstants.DOE_ALGORITHM_MONTE_CARLO)) && getOutputs(componentDescription).size() < 2) { final ComponentValidationMessage outputTooLow = new ComponentValidationMessage( ComponentValidationMessage.Type.ERROR, DOEConstants.KEY_METHOD, Messages.numOutputsG2Long, Messages.numOutputsG2Long); messages.add(outputTooLow); } if (getProperty(componentDescription, DOEConstants.KEY_METHOD).equals(DOEConstants.DOE_ALGORITHM_CUSTOM_TABLE)) { checkStartAndEndSample(componentDescription, messages); checkTableDimensions(componentDescription, messages); } if (getProperty(componentDescription, DOEConstants.KEY_METHOD).equals(DOEConstants.DOE_ALGORITHM_FULLFACT)) { if (getProperty(componentDescription, DOEConstants.KEY_RUN_NUMBER) == null || Integer.parseInt(getProperty(componentDescription, DOEConstants.KEY_RUN_NUMBER)) < 2) { final ComponentValidationMessage noInputMessage = new ComponentValidationMessage( ComponentValidationMessage.Type.ERROR, DOEConstants.KEY_RUN_NUMBER, Messages.numLevelsInvalidLong, Messages.numLevelsInvalidLong); messages.add(noInputMessage); } } return messages; } @Override protected List<ComponentValidationMessage> validateOnWorkflowStartComponentSpecific( ComponentDescription componentDescription) { // TODO Auto-generated method stub return null; } private void checkTableDimensions(ComponentDescription componentDescription, List<ComponentValidationMessage> messages) { String table = getProperty(componentDescription, DOEConstants.KEY_TABLE); if (table == null || table.isEmpty() || table.equals("null")) { final ComponentValidationMessage startSampleErrorMessage = new ComponentValidationMessage( ComponentValidationMessage.Type.ERROR, DOEConstants.KEY_TABLE, Messages.noTableLong, Messages.noTableLong); messages.add(startSampleErrorMessage); } else { ObjectMapper mapper = JsonUtils.getDefaultObjectMapper(); try { Double[][] tableValues = mapper.readValue(table, Double[][].class); if (tableValues != null && tableValues.length > 0 && (tableValues[0] != null && tableValues[0].length < getOutputs(componentDescription).size())) { final ComponentValidationMessage startSampleErrorMessage = new ComponentValidationMessage( ComponentValidationMessage.Type.ERROR, DOEConstants.KEY_TABLE, Messages.tableTooShortLong, Messages.tableTooShortLong); messages.add(startSampleErrorMessage); } if (tableValues != null && tableValues.length > 0 && tableValues[0].length > getOutputs(componentDescription).size()) { final ComponentValidationMessage startSampleErrorMessage = new ComponentValidationMessage( ComponentValidationMessage.Type.WARNING, DOEConstants.KEY_TABLE, Messages.tableTooLongLong, Messages.tableTooLongLong); messages.add(startSampleErrorMessage); } final ComponentValidationMessage noValueError = new ComponentValidationMessage( ComponentValidationMessage.Type.ERROR, DOEConstants.KEY_TABLE, Messages.undefinedValues, Messages.undefinedValues); for (int i = 0; (i < Integer .parseInt(getProperty(componentDescription, DOEConstants.KEY_RUN_NUMBER)) && (tableValues != null && i < tableValues.length)); i++) { for (int j = 0; j < tableValues[i].length; j++) { if (tableValues[i][j] == null) { messages.add(noValueError); break; } } if (messages.contains(noValueError)) { break; } } if (getProperty(componentDescription, DOEConstants.KEY_METHOD) .equals(DOEConstants.DOE_ALGORITHM_CUSTOM_TABLE) && (getProperty(componentDescription, DOEConstants.KEY_END_SAMPLE) != null && !getProperty(componentDescription, DOEConstants.KEY_END_SAMPLE).isEmpty() && Double.parseDouble(getProperty(componentDescription, DOEConstants.KEY_END_SAMPLE)) > Double.parseDouble( getProperty(componentDescription, DOEConstants.KEY_RUN_NUMBER)) - 1)) { final ComponentValidationMessage endSampleErrorMessage = new ComponentValidationMessage( ComponentValidationMessage.Type.ERROR, DOEConstants.KEY_END_SAMPLE, Messages.endSampleTooHighLong, Messages.endSampleTooHighLong); messages.add(endSampleErrorMessage); } } catch (IOException e) { final ComponentValidationMessage startSampleErrorMessage = new ComponentValidationMessage( ComponentValidationMessage.Type.ERROR, DOEConstants.KEY_TABLE, Messages.noTableLong, Messages.noTableLong); messages.add(startSampleErrorMessage); } } } private void checkStartAndEndSample(ComponentDescription componentDescription, final Collection<ComponentValidationMessage> messages) { String startSampleString = getProperty(componentDescription, DOEConstants.KEY_START_SAMPLE); Integer startSample = null; try { startSample = Integer.parseInt(startSampleString); } catch (NumberFormatException e) { final ComponentValidationMessage startSampleErrorMessage = new ComponentValidationMessage( ComponentValidationMessage.Type.ERROR, DOEConstants.KEY_START_SAMPLE, Messages.startSampleNotInteger, Messages.startSampleNotInteger); messages.add(startSampleErrorMessage); } if (startSample != null && startSample < 0) { final ComponentValidationMessage startSampleErrorMessage = new ComponentValidationMessage( ComponentValidationMessage.Type.ERROR, DOEConstants.KEY_START_SAMPLE, Messages.startSampleG0, Messages.startSampleG0); messages.add(startSampleErrorMessage); } if (startSample != null && startSample > Integer.parseInt(getProperty(componentDescription, DOEConstants.KEY_RUN_NUMBER))) { final ComponentValidationMessage startSampleErrorMessage = new ComponentValidationMessage( ComponentValidationMessage.Type.ERROR, DOEConstants.KEY_START_SAMPLE, Messages.startSampleTooHigh, Messages.startSampleTooHigh); messages.add(startSampleErrorMessage); } String endSampleString = getProperty(componentDescription, DOEConstants.KEY_END_SAMPLE); Integer endSample = null; try { endSample = Integer.parseInt(endSampleString); } catch (NumberFormatException e) { final ComponentValidationMessage startSampleErrorMessage = new ComponentValidationMessage( ComponentValidationMessage.Type.ERROR, DOEConstants.KEY_END_SAMPLE, Messages.endSampleNotInteger, Messages.endSampleNotInteger); messages.add(startSampleErrorMessage); } if (endSample != null && endSample < 0) { final ComponentValidationMessage startSampleErrorMessage = new ComponentValidationMessage( ComponentValidationMessage.Type.ERROR, DOEConstants.KEY_END_SAMPLE, Messages.endSampleG0, Messages.endSampleG0); messages.add(startSampleErrorMessage); } if (startSample == null || endSample == null || startSample > endSample) { final ComponentValidationMessage startSampleErrorMessage = new ComponentValidationMessage( ComponentValidationMessage.Type.ERROR, DOEConstants.KEY_END_SAMPLE, Messages.endSampleGStart, Messages.endSampleGStart); messages.add(startSampleErrorMessage); } } @Override protected Set<EndpointDescription> getOutputs(ComponentDescription componentDescription) { Set<EndpointDescription> outputs = new HashSet<>(super.getOutputs(componentDescription)); Iterator<EndpointDescription> outputsIterator = outputs.iterator(); while (outputsIterator.hasNext()) { EndpointDescription next = outputsIterator.next(); if (LoopComponentConstants.ENDPOINT_ID_TO_FORWARD.equals(next.getDynamicEndpointIdentifier()) || LoopComponentConstants.ENDPOINT_NAME_LOOP_DONE.equals(next.getName()) || DOEConstants.OUTPUT_NAME_NUMBER_OF_SAMPLES.equals(next.getName())) { outputsIterator.remove(); } } return outputs; } }