/* * Copyright (C) 2006-2016 DLR, Germany * * All rights reserved * * http://www.rcenvironment.de/ */ package de.rcenvironment.core.component.validation.spi; import java.util.ArrayList; import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Set; import de.rcenvironment.core.component.api.ComponentConstants; import de.rcenvironment.core.component.model.api.ComponentDescription; import de.rcenvironment.core.component.model.endpoint.api.EndpointDefinition; import de.rcenvironment.core.component.model.endpoint.api.EndpointDescription; import de.rcenvironment.core.component.validation.api.ComponentValidationMessage; import de.rcenvironment.core.datamodel.api.DataType; import de.rcenvironment.core.utils.common.StringUtils; /** * Contains base implementation of a validator. Validation code that is done for every component should be inside this class. * * All validators should extend this class. * * @author Jascha Riedel * */ public abstract class AbstractComponentValidator implements ComponentValidator { /** * Here should be all validation steps that are specific to the implementing component. (If there are steps only required on workflow * start, describe them in validateOnWorkflowStartComponentSepcific(...)). If there are none return null. * * @param componentDescription {@link ComponentDescription} of the component instance. * @return */ protected abstract List<ComponentValidationMessage> validateComponentSpecific( ComponentDescription componentDescription); /** * Here should be all validation steps that are specific to the implementing component and only required on workflow start. If there are * none return null. * * @param componentDescription {@link ComponentDescription} of the component instance. * @return */ protected abstract List<ComponentValidationMessage> validateOnWorkflowStartComponentSpecific( ComponentDescription componentDescription); @Override public List<ComponentValidationMessage> validate(ComponentDescription componentDescription, boolean onWorkflowStart) { List<ComponentValidationMessage> messages = new ArrayList<>(); messages.addAll(defaultValidations(componentDescription)); List<ComponentValidationMessage> componentSpecificMessages = validateComponentSpecific(componentDescription); if (componentSpecificMessages != null) { messages.addAll(componentSpecificMessages); } if (onWorkflowStart) { messages.addAll(validateOnWorkflowStart(componentDescription)); } return messages; } protected List<ComponentValidationMessage> validateOnWorkflowStart(ComponentDescription componentDescription) { List<ComponentValidationMessage> messages = new ArrayList<>(); // No default validation steps List<ComponentValidationMessage> componentSpecificMessages = validateOnWorkflowStartComponentSpecific( componentDescription); if (componentSpecificMessages != null) { messages.addAll(componentSpecificMessages); } return messages; } /** * The default validations that are done for every component should be placed here. */ protected List<ComponentValidationMessage> defaultValidations(ComponentDescription componentDescription) { List<ComponentValidationMessage> messages = new ArrayList<>(); messages.addAll(validateInputExecutionConstraints(componentDescription)); return messages; } protected List<ComponentValidationMessage> validateInputExecutionConstraints( ComponentDescription componentDescription) { List<ComponentValidationMessage> m = new LinkedList<>(); for (EndpointDescription inputEp : getInputs(componentDescription)) { EndpointDefinition.InputExecutionContraint exeConstraint = inputEp.getEndpointDefinition() .getDefaultInputExecutionConstraint(); if (inputEp.getMetaDataValue(ComponentConstants.INPUT_METADATA_KEY_INPUT_EXECUTION_CONSTRAINT) != null) { exeConstraint = EndpointDefinition.InputExecutionContraint.valueOf( inputEp.getMetaDataValue(ComponentConstants.INPUT_METADATA_KEY_INPUT_EXECUTION_CONSTRAINT)); } if (exeConstraint.equals(EndpointDefinition.InputExecutionContraint.Required) && !inputEp.isConnected()) { m.add(new ComponentValidationMessage(ComponentValidationMessage.Type.ERROR, "", StringUtils.format( "Connect input '%s' to an output (of an enabled component) as it is required", inputEp.getName()), StringUtils.format("Input '%s' is required but not connected to an output", inputEp.getName()))); } } return m; } protected Set<EndpointDescription> getInputs(ComponentDescription componentDescription) { return componentDescription.getInputDescriptionsManager().getEndpointDescriptions(); } protected Set<EndpointDescription> getInputs(ComponentDescription componentDescription, DataType dataType) { Set<EndpointDescription> returnSet = new HashSet<>(); for (EndpointDescription endpointDescription : componentDescription.getInputDescriptionsManager() .getEndpointDescriptions()) { if (endpointDescription.getDataType().equals(dataType)) { returnSet.add(endpointDescription); } } return returnSet; } protected boolean hasInputs(ComponentDescription componentDescription) { return !componentDescription.getInputDescriptionsManager().getEndpointDescriptions().isEmpty(); } protected Set<EndpointDescription> getOutputs(ComponentDescription componentDescription) { return componentDescription.getOutputDescriptionsManager().getEndpointDescriptions(); } protected Set<EndpointDescription> getOutputs(ComponentDescription componentDescription, DataType dataType) { Set<EndpointDescription> returnSet = new HashSet<>(); for (EndpointDescription endpointDescription : componentDescription.getOutputDescriptionsManager() .getEndpointDescriptions()) { if (endpointDescription.getDataType().equals(dataType)) { returnSet.add(endpointDescription); } } return returnSet; } protected String getProperty(ComponentDescription componentDescription, String property) { return componentDescription.getConfigurationDescription().getConfigurationValue(property); } protected boolean isPropertySet(ComponentDescription componentDescription, String property) { return getProperty(componentDescription, property) != null; } }