Search in sources :

Example 1 with PrimitiveDataType

use of org.alien4cloud.tosca.model.types.PrimitiveDataType in project alien4cloud by alien4cloud.

the class ToscaPropertyFormDescriptorGenerator method generateDescriptorForDataType.

private Map<String, Object> generateDescriptorForDataType(Set<String> processedDataTypes, DataType dataType, Set<CSARDependency> dependencies) {
    Map<String, Object> dataTypeDescriptors = Maps.newHashMap();
    if (dataType instanceof PrimitiveDataType) {
        dataTypeDescriptors.put(TYPE_KEY, TOSCA_TYPE);
        PropertyDefinition propertyDefinition = new PropertyDefinition();
        propertyDefinition.setType(dataType.getDerivedFrom().get(0));
        propertyDefinition.setConstraints(((PrimitiveDataType) dataType).getConstraints());
        dataTypeDescriptors.put(TOSCA_DEFINITION_KEY, propertyDefinition);
    } else {
        dataTypeDescriptors.put(TYPE_KEY, COMPLEX_TYPE);
        Map<String, Object> propertyTypes = Maps.newHashMap();
        dataTypeDescriptors.put(PROPERTY_TYPE_KEY, propertyTypes);
        if (dataType.getProperties() != null) {
            for (Map.Entry<String, PropertyDefinition> propertyDefinitionEntry : dataType.getProperties().entrySet()) {
                propertyTypes.put(propertyDefinitionEntry.getKey(), doGenerateDescriptor(processedDataTypes, propertyDefinitionEntry.getValue(), dependencies));
            }
            dataTypeDescriptors.put(ORDER_KEY, dataType.getProperties().keySet());
        }
    }
    return dataTypeDescriptors;
}
Also used : PrimitiveDataType(org.alien4cloud.tosca.model.types.PrimitiveDataType) PropertyDefinition(org.alien4cloud.tosca.model.definitions.PropertyDefinition) Map(java.util.Map)

Example 2 with PrimitiveDataType

use of org.alien4cloud.tosca.model.types.PrimitiveDataType in project alien4cloud by alien4cloud.

the class ConstraintPropertyService method checkPropertyConstraint.

/**
 * Check the constraints on an unwrapped property value (basically a string, map or list) and get events through the given consumer parameter when missing
 * properties on complex data type are found.
 * Note that the property value cannot be null and the required characteristic of the initial property definition will NOT be checked.
 *
 * @param propertyName The name of the property.
 * @param propertyValue The value of the property to check.
 * @param propertyDefinition The property definition that defines the property to check.
 * @param missingPropertyConsumer A consumer to receive events when a required property is not defined on a complex type sub-field.
 * @throws ConstraintValueDoNotMatchPropertyTypeException In case the value type doesn't match the type of the property as defined.
 * @throws ConstraintViolationException In case the value doesn't match one of the constraints defined on the property.
 */
public static void checkPropertyConstraint(String propertyName, Object propertyValue, PropertyDefinition propertyDefinition, Consumer<String> missingPropertyConsumer) throws ConstraintValueDoNotMatchPropertyTypeException, ConstraintViolationException {
    Object value = propertyValue;
    if (propertyValue instanceof PropertyValue) {
        value = ((PropertyValue) propertyValue).getValue();
    }
    boolean isTypeDerivedFromPrimitive = false;
    DataType dataType = null;
    String typeName = propertyDefinition.getType();
    if (!ToscaTypes.isPrimitive(typeName)) {
        dataType = ToscaContext.get(DataType.class, typeName);
        if (dataType instanceof PrimitiveDataType) {
            // the type is derived from a primitive type
            isTypeDerivedFromPrimitive = true;
        }
    }
    if (value instanceof String) {
        if (ToscaTypes.isSimple(typeName)) {
            checkSimplePropertyConstraint(propertyName, (String) value, propertyDefinition);
        } else if (isTypeDerivedFromPrimitive) {
            checkComplexPropertyDerivedFromPrimitiveTypeConstraints(propertyName, (String) value, propertyDefinition, dataType);
        } else {
            throwConstraintValueDoNotMatchPropertyTypeException("Property value is a String while the expected data type is the complex type " + propertyDefinition.getType(), propertyName, propertyDefinition.getType(), value);
        }
    } else if (value instanceof Map) {
        if (ToscaTypes.MAP.equals(typeName)) {
            checkMapPropertyConstraint(propertyName, (Map<String, Object>) value, propertyDefinition, missingPropertyConsumer);
        } else {
            checkDataTypePropertyConstraint(propertyName, (Map<String, Object>) value, propertyDefinition, missingPropertyConsumer);
        }
    } else if (value instanceof List) {
        // Range type is a specific primitive type that is actually wrapped
        if (ToscaTypes.RANGE.equals(typeName)) {
            checkRangePropertyConstraint(propertyName, (List<Object>) value, propertyDefinition);
        } else {
            checkListPropertyConstraint(propertyName, (List<Object>) value, propertyDefinition, missingPropertyConsumer);
        }
    } else {
        throw new InvalidArgumentException("Not expecting to receive constraint validation for other types than String, Map or List, but got " + value.getClass().getName());
    }
}
Also used : PrimitiveDataType(org.alien4cloud.tosca.model.types.PrimitiveDataType) InvalidArgumentException(alien4cloud.exception.InvalidArgumentException) PropertyValue(org.alien4cloud.tosca.model.definitions.PropertyValue) DataType(org.alien4cloud.tosca.model.types.DataType) PrimitiveDataType(org.alien4cloud.tosca.model.types.PrimitiveDataType) List(java.util.List) Map(java.util.Map)

Example 3 with PrimitiveDataType

use of org.alien4cloud.tosca.model.types.PrimitiveDataType in project alien4cloud by alien4cloud.

the class ConstraintPropertyService method checkComplexPropertyDerivedFromPrimitiveTypeConstraints.

/**
 * Check constraints defined on a property which has a type derived from a primitive.
 */
private static void checkComplexPropertyDerivedFromPrimitiveTypeConstraints(final String propertyName, final String stringValue, final PropertyDefinition propertyDefinition, final DataType dataType) throws ConstraintViolationException, ConstraintValueDoNotMatchPropertyTypeException {
    ConstraintInformation consInformation = null;
    boolean hasDefinitionConstraints = propertyDefinition.getConstraints() != null && !propertyDefinition.getConstraints().isEmpty();
    boolean hasTypeConstraints = false;
    if (dataType instanceof PrimitiveDataType && ((PrimitiveDataType) dataType).getConstraints() != null && !((PrimitiveDataType) dataType).getConstraints().isEmpty()) {
        hasTypeConstraints = true;
    }
    String derivedFromPrimitiveType = dataType.getDerivedFrom().get(0);
    // Check the type of the property even if there is no constraints.
    checkBasicType(propertyName, derivedFromPrimitiveType, stringValue);
    if (hasDefinitionConstraints || hasTypeConstraints) {
        // check the constraints if there is any defined
        if (hasDefinitionConstraints) {
            checkConstraints(propertyName, stringValue, derivedFromPrimitiveType, propertyDefinition.getConstraints());
        }
        if (hasTypeConstraints) {
            checkConstraints(propertyName, stringValue, derivedFromPrimitiveType, ((PrimitiveDataType) dataType).getConstraints());
        }
    }
}
Also used : PrimitiveDataType(org.alien4cloud.tosca.model.types.PrimitiveDataType) ConstraintInformation(alien4cloud.tosca.properties.constraints.ConstraintUtil.ConstraintInformation)

Example 4 with PrimitiveDataType

use of org.alien4cloud.tosca.model.types.PrimitiveDataType in project alien4cloud by alien4cloud.

the class DerivedFromPostProcessor method process.

private void process(Map<AbstractInheritableToscaType, String> processed, Map<AbstractInheritableToscaType, String> processing, AbstractInheritableToscaType instance, Map<String, ? extends AbstractInheritableToscaType> instances) {
    if (processed.containsKey(instance)) {
        // Already processed
        return;
    }
    if (processing.containsKey(instance)) {
        // Cyclic dependency as parent is currently being processed...
        Node node = ParsingContextExecution.getObjectToNodeMap().get(instance);
        ParsingContextExecution.getParsingErrors().add(new ParsingError(ErrorCode.CYCLIC_DERIVED_FROM, "Cyclic derived from has been detected", node.getStartMark(), "The type specified as parent or one of it's parent type refers the current type as parent, invalid cycle detected.", node.getEndMark(), instance.getElementId()));
        processing.remove(instance);
        return;
    }
    List<String> derivedFrom = instance.getDerivedFrom();
    if (derivedFrom != null && derivedFrom.size() > 1) {
        // The type has been already processed.
        return;
    }
    if (derivedFrom == null || derivedFrom.isEmpty()) {
        // If the user forgot to derive from Root, automatically do it but make an alert
        String defaultDerivedFrom = null;
        if (instance instanceof NodeType && !NormativeTypesConstant.ROOT_NODE_TYPE.equals(instance.getElementId())) {
            defaultDerivedFrom = NormativeTypesConstant.ROOT_NODE_TYPE;
        } else if (instance instanceof RelationshipType && !NormativeTypesConstant.ROOT_RELATIONSHIP_TYPE.equals(instance.getElementId())) {
            defaultDerivedFrom = NormativeTypesConstant.ROOT_RELATIONSHIP_TYPE;
        } else if (instance instanceof DataType && !NormativeTypesConstant.ROOT_DATA_TYPE.equals(instance.getElementId())) {
            defaultDerivedFrom = NormativeTypesConstant.ROOT_DATA_TYPE;
        } else if (instance instanceof CapabilityType && !NormativeCapabilityTypes.ROOT.equals(instance.getElementId())) {
            defaultDerivedFrom = NormativeCapabilityTypes.ROOT;
        } else if (instance instanceof ArtifactType && !NormativeTypesConstant.ROOT_ARTIFACT_TYPE.equals(instance.getElementId())) {
            defaultDerivedFrom = NormativeTypesConstant.ROOT_ARTIFACT_TYPE;
        }
        if (defaultDerivedFrom != null) {
            derivedFrom = new ArrayList<>();
            derivedFrom.add(defaultDerivedFrom);
            instance.setDerivedFrom(derivedFrom);
            Node node = ParsingContextExecution.getObjectToNodeMap().get(instance);
            ParsingContextExecution.getParsingErrors().add(new ParsingError(ParsingErrorLevel.WARNING, ErrorCode.DERIVED_FROM_NOTHING, defaultDerivedFrom, node.getStartMark(), "The " + instance.getClass().getSimpleName() + " " + instance.getElementId() + " derives from nothing, default " + defaultDerivedFrom + " will be set as parent type.", node.getEndMark(), instance.getElementId()));
        } else {
            // Non managed default parent type then returns
            return;
        }
    }
    String parentElementType = derivedFrom.get(0);
    // Merge the type with it's parent except for primitive data types.
    if (instance instanceof DataType && ToscaTypes.isSimple(parentElementType)) {
        if (instance instanceof PrimitiveDataType) {
            log.debug("Do not merge data type instance with parent as it extends from a primitive type.");
        } else {
            Node node = ParsingContextExecution.getObjectToNodeMap().get(instance);
            // type has not been parsed as primitive because it has some properties
            ParsingContextExecution.getParsingErrors().add(new ParsingError(ErrorCode.SYNTAX_ERROR, "Primitive types cannot define properties.", node.getStartMark(), "The defined type inherit from a primitive type but defines some properties.", node.getEndMark(), parentElementType));
        }
        return;
    }
    AbstractInheritableToscaType parent = instances.get(parentElementType);
    if (parent == null) {
        parent = ToscaContext.get(instance.getClass(), parentElementType);
    } else {
        // first process the parent type
        processing.put(instance, null);
        process(processed, processing, parent, instances);
        processing.remove(instance);
    }
    if (parent == null) {
        Node node = ParsingContextExecution.getObjectToNodeMap().get(instance);
        ParsingContextExecution.getParsingErrors().add(new ParsingError(ErrorCode.TYPE_NOT_FOUND, "Derived_from type not found", node.getStartMark(), "The type specified as parent is not found neither in the archive or its dependencies.", node.getEndMark(), parentElementType));
        return;
    }
    // Merge with parent type
    IndexedModelUtils.mergeInheritableIndex(parent, instance);
    processed.put(instance, null);
}
Also used : CapabilityType(org.alien4cloud.tosca.model.types.CapabilityType) ParsingError(alien4cloud.tosca.parser.ParsingError) PrimitiveDataType(org.alien4cloud.tosca.model.types.PrimitiveDataType) ArtifactType(org.alien4cloud.tosca.model.types.ArtifactType) Node(org.yaml.snakeyaml.nodes.Node) NodeType(org.alien4cloud.tosca.model.types.NodeType) RelationshipType(org.alien4cloud.tosca.model.types.RelationshipType) DataType(org.alien4cloud.tosca.model.types.DataType) PrimitiveDataType(org.alien4cloud.tosca.model.types.PrimitiveDataType) AbstractInheritableToscaType(org.alien4cloud.tosca.model.types.AbstractInheritableToscaType)

Aggregations

PrimitiveDataType (org.alien4cloud.tosca.model.types.PrimitiveDataType)4 Map (java.util.Map)2 DataType (org.alien4cloud.tosca.model.types.DataType)2 InvalidArgumentException (alien4cloud.exception.InvalidArgumentException)1 ParsingError (alien4cloud.tosca.parser.ParsingError)1 ConstraintInformation (alien4cloud.tosca.properties.constraints.ConstraintUtil.ConstraintInformation)1 List (java.util.List)1 PropertyDefinition (org.alien4cloud.tosca.model.definitions.PropertyDefinition)1 PropertyValue (org.alien4cloud.tosca.model.definitions.PropertyValue)1 AbstractInheritableToscaType (org.alien4cloud.tosca.model.types.AbstractInheritableToscaType)1 ArtifactType (org.alien4cloud.tosca.model.types.ArtifactType)1 CapabilityType (org.alien4cloud.tosca.model.types.CapabilityType)1 NodeType (org.alien4cloud.tosca.model.types.NodeType)1 RelationshipType (org.alien4cloud.tosca.model.types.RelationshipType)1 Node (org.yaml.snakeyaml.nodes.Node)1