Search in sources :

Example 1 with NullSafeTypeAnnotation

use of org.mule.runtime.extension.api.declaration.type.annotation.NullSafeTypeAnnotation in project mule by mulesoft.

the class NullSafeModelValidator method validate.

@Override
public void validate(ExtensionModel extensionModel, ProblemsReporter problemsReporter) {
    ReflectionCache reflectionCache = new ReflectionCache();
    TypeLoader typeLoader = ExtensionsTypeLoaderFactory.getDefault().createTypeLoader();
    new ExtensionWalker() {

        @Override
        public void onParameter(ParameterizedModel owner, ParameterGroupModel groupModel, ParameterModel model) {
            model.getType().accept(new MetadataTypeVisitor() {

                @Override
                public void visitObject(ObjectType objectType) {
                    if (objectType.getMetadataFormat().equals(JAVA) && !isMap(objectType)) {
                        objectType.getAnnotation(TypeIdAnnotation.class).map(TypeIdAnnotation::getValue).ifPresent(typeId -> typeLoader.load(typeId).ifPresent(fieldMetadataType -> objectType.getFields().stream().filter(f -> f.getAnnotation(NullSafeTypeAnnotation.class).isPresent()).forEach(f -> validateField(getLocalPart(f), f, getType(fieldMetadataType), f.getAnnotation(NullSafeTypeAnnotation.class).get()))));
                    }
                }

                private void validateField(String fieldName, ObjectFieldType field, Class<?> declaringClass, NullSafeTypeAnnotation nullSafeTypeAnnotation) {
                    Class<?> nullSafeType = nullSafeTypeAnnotation.getType();
                    Class<?> fieldType = getType(field.getValue());
                    boolean hasDefaultOverride = nullSafeTypeAnnotation.hasDefaultOverride();
                    field.getValue().accept(new BasicTypeMetadataVisitor() {

                        @Override
                        protected void visitBasicType(MetadataType metadataType) {
                            problemsReporter.addError(new Problem(extensionModel, format("Field '%s' in class '%s' is annotated with '@%s' but is of type '%s'. That annotation can only be " + "used with complex types (Pojos, Lists, Maps)", fieldName, declaringClass.getName(), NullSafe.class.getSimpleName(), fieldType.getName())));
                        }

                        @Override
                        public void visitArrayType(ArrayType arrayType) {
                            if (hasDefaultOverride) {
                                problemsReporter.addError(new Problem(extensionModel, format("Field '%s' in class '%s' is annotated with '@%s' is of type '%s'" + " but a 'defaultImplementingType' was provided." + " Type override is not allowed for Collections", fieldName, declaringClass.getName(), NullSafe.class.getSimpleName(), fieldType.getName())));
                            }
                        }

                        @Override
                        public void visitObject(ObjectType objectType) {
                            String requiredFields = objectType.getFields().stream().filter(f -> f.isRequired() && !isFlattenedParameterGroup(f)).map(MetadataTypeUtils::getLocalPart).collect(joining(", "));
                            if (!isBlank(requiredFields) && isCompiletime(extensionModel)) {
                                problemsReporter.addError(new Problem(model, format("Class '%s' cannot be used with '@%s' parameter since it contains non optional fields: [%s]", getId(objectType).orElse(""), NullSafe.class.getSimpleName(), requiredFields)));
                            }
                            if (objectType.isOpen()) {
                                if (hasDefaultOverride) {
                                    problemsReporter.addError(new Problem(model, format("Field '%s' in class '%s' is annotated with '@%s' is of type '%s'" + " but a 'defaultImplementingType' was provided." + " Type override is not allowed for Maps", fieldName, declaringClass.getName(), NullSafe.class.getSimpleName(), fieldType.getName())));
                                }
                                return;
                            }
                            if (hasDefaultOverride && isInstantiable(fieldType, reflectionCache)) {
                                problemsReporter.addError(new Problem(model, format("Field '%s' in class '%s' is annotated with '@%s' is of concrete type '%s'," + " but a 'defaultImplementingType' was provided." + " Type override is not allowed for concrete types", fieldName, declaringClass.getName(), NullSafe.class.getSimpleName(), fieldType.getName())));
                            }
                            if (!isInstantiable(nullSafeType, reflectionCache)) {
                                problemsReporter.addError(new Problem(model, format("Field '%s' in class '%s' is annotated with '@%s' but is of type '%s'. That annotation can only be " + "used with complex instantiable types (Pojos, Lists, Maps)", fieldName, declaringClass.getName(), NullSafe.class.getSimpleName(), nullSafeType.getName())));
                            }
                            if (hasDefaultOverride && !fieldType.isAssignableFrom(nullSafeType)) {
                                problemsReporter.addError(new Problem(model, format("Field '%s' in class '%s' is annotated with '@%s' of type '%s', but provided type '%s" + " is not a subtype of the parameter's type", fieldName, declaringClass.getName(), NullSafe.class.getSimpleName(), fieldType.getName(), nullSafeType.getName())));
                            }
                        }
                    });
                }
            });
        }
    }.walk(extensionModel);
}
Also used : ExtensionMetadataTypeUtils.getId(org.mule.runtime.extension.api.util.ExtensionMetadataTypeUtils.getId) ParameterModel(org.mule.runtime.api.meta.model.parameter.ParameterModel) ExtensionsTypeLoaderFactory(org.mule.runtime.extension.api.declaration.type.ExtensionsTypeLoaderFactory) JAVA(org.mule.metadata.api.model.MetadataFormat.JAVA) MetadataTypeUtils(org.mule.metadata.api.utils.MetadataTypeUtils) ExtensionMetadataTypeUtils.isFlattenedParameterGroup(org.mule.runtime.extension.api.util.ExtensionMetadataTypeUtils.isFlattenedParameterGroup) ModelValidationUtils.isCompiletime(org.mule.runtime.module.extension.internal.loader.validation.ModelValidationUtils.isCompiletime) ArrayType(org.mule.metadata.api.model.ArrayType) BasicTypeMetadataVisitor(org.mule.metadata.api.visitor.BasicTypeMetadataVisitor) ParameterGroupModel(org.mule.runtime.api.meta.model.parameter.ParameterGroupModel) IntrospectionUtils.isInstantiable(org.mule.runtime.module.extension.internal.util.IntrospectionUtils.isInstantiable) Problem(org.mule.runtime.extension.api.loader.Problem) MetadataTypeUtils.getLocalPart(org.mule.metadata.api.utils.MetadataTypeUtils.getLocalPart) TypeIdAnnotation(org.mule.metadata.api.annotation.TypeIdAnnotation) ExtensionModelValidator(org.mule.runtime.extension.api.loader.ExtensionModelValidator) ExtensionMetadataTypeUtils.isMap(org.mule.runtime.extension.api.util.ExtensionMetadataTypeUtils.isMap) ObjectType(org.mule.metadata.api.model.ObjectType) ParameterizedModel(org.mule.runtime.api.meta.model.parameter.ParameterizedModel) ProblemsReporter(org.mule.runtime.extension.api.loader.ProblemsReporter) NullSafeTypeAnnotation(org.mule.runtime.extension.api.declaration.type.annotation.NullSafeTypeAnnotation) ReflectionCache(org.mule.runtime.module.extension.internal.util.ReflectionCache) String.format(java.lang.String.format) Collectors.joining(java.util.stream.Collectors.joining) MetadataTypeVisitor(org.mule.metadata.api.visitor.MetadataTypeVisitor) TypeLoader(org.mule.metadata.api.TypeLoader) ExtensionModel(org.mule.runtime.api.meta.model.ExtensionModel) ObjectFieldType(org.mule.metadata.api.model.ObjectFieldType) StringUtils.isBlank(org.apache.commons.lang3.StringUtils.isBlank) ExtensionWalker(org.mule.runtime.api.meta.model.util.ExtensionWalker) NullSafe(org.mule.runtime.extension.api.annotation.param.NullSafe) MetadataType(org.mule.metadata.api.model.MetadataType) JavaTypeUtils.getType(org.mule.metadata.java.api.utils.JavaTypeUtils.getType) ReflectionCache(org.mule.runtime.module.extension.internal.util.ReflectionCache) ExtensionWalker(org.mule.runtime.api.meta.model.util.ExtensionWalker) MetadataType(org.mule.metadata.api.model.MetadataType) TypeLoader(org.mule.metadata.api.TypeLoader) NullSafeTypeAnnotation(org.mule.runtime.extension.api.declaration.type.annotation.NullSafeTypeAnnotation) MetadataTypeVisitor(org.mule.metadata.api.visitor.MetadataTypeVisitor) MetadataTypeUtils(org.mule.metadata.api.utils.MetadataTypeUtils) BasicTypeMetadataVisitor(org.mule.metadata.api.visitor.BasicTypeMetadataVisitor) ArrayType(org.mule.metadata.api.model.ArrayType) ObjectType(org.mule.metadata.api.model.ObjectType) ParameterModel(org.mule.runtime.api.meta.model.parameter.ParameterModel) ParameterizedModel(org.mule.runtime.api.meta.model.parameter.ParameterizedModel) ParameterGroupModel(org.mule.runtime.api.meta.model.parameter.ParameterGroupModel) Problem(org.mule.runtime.extension.api.loader.Problem) ObjectFieldType(org.mule.metadata.api.model.ObjectFieldType)

Example 2 with NullSafeTypeAnnotation

use of org.mule.runtime.extension.api.declaration.type.annotation.NullSafeTypeAnnotation in project mule by mulesoft.

the class ParametersResolver method resolveParameters.

/**
 * {@inheritDoc}
 */
@Override
public void resolveParameters(ObjectType objectType, DefaultObjectBuilder builder) {
    final Class<?> objectClass = getType(objectType);
    final boolean isParameterGroup = isFlattenedParameterGroup(objectType);
    objectType.getFields().forEach(field -> {
        final String key = getLocalPart(field);
        ValueResolver<?> valueResolver = null;
        Field objectField = getField(objectClass, key);
        if (parameters.containsKey(key)) {
            valueResolver = toValueResolver(parameters.get(key));
        } else if (!isParameterGroup) {
            valueResolver = getDefaultValue(field).isPresent() ? getFieldDefaultValueValueResolver(field, muleContext) : null;
        }
        Optional<NullSafeTypeAnnotation> nullSafe = field.getAnnotation(NullSafeTypeAnnotation.class);
        if (nullSafe.isPresent()) {
            ValueResolver<?> delegate = valueResolver != null ? valueResolver : new StaticValueResolver<>(null);
            MetadataType type = getMetadataType(nullSafe.get().getType(), ExtensionsTypeLoaderFactory.getDefault().createTypeLoader());
            valueResolver = NullSafeValueResolverWrapper.of(delegate, type, reflectionCache, muleContext, this);
        }
        if (field.getAnnotation(ConfigOverrideTypeAnnotation.class).isPresent()) {
            valueResolver = ConfigOverrideValueResolverWrapper.of(valueResolver != null ? valueResolver : new StaticValueResolver<>(null), key, reflectionCache, muleContext);
        }
        if (valueResolver != null) {
            try {
                initialiseIfNeeded(valueResolver, true, muleContext);
                builder.addPropertyResolver(objectField.getName(), valueResolver);
            } catch (InitialisationException e) {
                throw new MuleRuntimeException(e);
            }
        } else if (field.isRequired() && !isFlattenedParameterGroup(field) && !lazyInitEnabled) {
            throw new RequiredParameterNotSetException(objectField.getName());
        }
    });
}
Also used : RequiredParameterNotSetException(org.mule.runtime.module.extension.internal.runtime.exception.RequiredParameterNotSetException) MetadataType(org.mule.metadata.api.model.MetadataType) IntrospectionUtils.getMetadataType(org.mule.runtime.module.extension.internal.util.IntrospectionUtils.getMetadataType) InitialisationException(org.mule.runtime.api.lifecycle.InitialisationException) NullSafeTypeAnnotation(org.mule.runtime.extension.api.declaration.type.annotation.NullSafeTypeAnnotation) Field(java.lang.reflect.Field) MuleRuntimeException(org.mule.runtime.api.exception.MuleRuntimeException) ConfigOverrideTypeAnnotation(org.mule.runtime.extension.api.declaration.type.annotation.ConfigOverrideTypeAnnotation)

Aggregations

MetadataType (org.mule.metadata.api.model.MetadataType)2 NullSafeTypeAnnotation (org.mule.runtime.extension.api.declaration.type.annotation.NullSafeTypeAnnotation)2 String.format (java.lang.String.format)1 Field (java.lang.reflect.Field)1 Collectors.joining (java.util.stream.Collectors.joining)1 StringUtils.isBlank (org.apache.commons.lang3.StringUtils.isBlank)1 TypeLoader (org.mule.metadata.api.TypeLoader)1 TypeIdAnnotation (org.mule.metadata.api.annotation.TypeIdAnnotation)1 ArrayType (org.mule.metadata.api.model.ArrayType)1 JAVA (org.mule.metadata.api.model.MetadataFormat.JAVA)1 ObjectFieldType (org.mule.metadata.api.model.ObjectFieldType)1 ObjectType (org.mule.metadata.api.model.ObjectType)1 MetadataTypeUtils (org.mule.metadata.api.utils.MetadataTypeUtils)1 MetadataTypeUtils.getLocalPart (org.mule.metadata.api.utils.MetadataTypeUtils.getLocalPart)1 BasicTypeMetadataVisitor (org.mule.metadata.api.visitor.BasicTypeMetadataVisitor)1 MetadataTypeVisitor (org.mule.metadata.api.visitor.MetadataTypeVisitor)1 JavaTypeUtils.getType (org.mule.metadata.java.api.utils.JavaTypeUtils.getType)1 MuleRuntimeException (org.mule.runtime.api.exception.MuleRuntimeException)1 InitialisationException (org.mule.runtime.api.lifecycle.InitialisationException)1 ExtensionModel (org.mule.runtime.api.meta.model.ExtensionModel)1