Search in sources :

Example 1 with ArrayParamParser

use of ninja.params.ParamParsers.ArrayParamParser in project ninja by ninjaframework.

the class BodyParserEnginePost method invoke.

// Allows to instantiate inner objects with a prefix for each parameter key
private <T> T invoke(Context context, Map<String, String[]> parameters, Class<T> classOfT, String paramPrefix) {
    T t = null;
    try {
        t = classOfT.newInstance();
    } catch (InstantiationException | IllegalAccessException e) {
        logger.error("Can't create new instance of class {}", classOfT.getName(), e);
        return null;
    }
    for (String declaredField : getAllDeclaredFieldsAsStringSet(classOfT)) {
        try {
            Field field = classOfT.getDeclaredField(declaredField);
            Class<?> fieldType = field.getType();
            field.setAccessible(true);
            if (parameters.containsKey(paramPrefix + declaredField)) {
                String[] values = parameters.get(paramPrefix + declaredField);
                if (Collection.class.isAssignableFrom(fieldType) || List.class.isAssignableFrom(fieldType)) {
                    ListParamParser<?> parser = (ListParamParser<?>) paramParsers.getListParser(getGenericType(field));
                    if (parser == null) {
                        logger.warn("No parser defined for a collection of type {}", getGenericType(field).getCanonicalName());
                    } else {
                        field.set(t, parser.parseParameter(field.getName(), values, context.getValidation()));
                    }
                } else if (fieldType.isArray()) {
                    ArrayParamParser<?> parser = paramParsers.getArrayParser(fieldType);
                    if (parser == null) {
                        logger.warn("No parser defined for an array of type {}", fieldType.getComponentType().getCanonicalName());
                    } else {
                        field.set(t, parser.parseParameter(field.getName(), values, context.getValidation()));
                    }
                } else {
                    ParamParser<?> parser = (ParamParser<?>) paramParsers.getParamParser(fieldType);
                    if (parser == null) {
                        logger.warn("No parser defined for type {}", fieldType.getCanonicalName());
                    } else {
                        field.set(t, parser.parseParameter(field.getName(), values[0], context.getValidation()));
                    }
                }
            } else {
                // Check if we have one parameter key corresponding to one valued inner attribute of this object field
                for (String parameter : parameters.keySet()) {
                    if (parameter.startsWith(paramPrefix + declaredField + ".")) {
                        if (isEmptyParameter(parameters.get(parameter))) {
                            field.set(t, invoke(context, parameters, fieldType, paramPrefix + declaredField + "."));
                            break;
                        }
                    }
                }
            }
        } catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) {
            logger.warn("Error parsing incoming Post request into class {}. Key {} and value {}.", classOfT.getName(), paramPrefix + declaredField, parameters.get(paramPrefix + declaredField), e);
        }
    }
    return t;
}
Also used : ListParamParser(ninja.params.ParamParsers.ListParamParser) ParamParser(ninja.params.ParamParser) ArrayParamParser(ninja.params.ParamParsers.ArrayParamParser) ListParamParser(ninja.params.ParamParsers.ListParamParser) Field(java.lang.reflect.Field) Collection(java.util.Collection) List(java.util.List) ArrayParamParser(ninja.params.ParamParsers.ArrayParamParser)

Example 2 with ArrayParamParser

use of ninja.params.ParamParsers.ArrayParamParser in project ninja by ninjaframework.

the class ControllerMethodInvoker method validateArgumentWithExtractor.

private static ArgumentExtractor<?> validateArgumentWithExtractor(MethodParameter methodParameter, Annotation[] annotations, Injector injector, ArgumentExtractor<?> extractor) {
    // We have validators that get applied before parsing, and validators
    // that get applied after parsing.
    List<Validator<?>> preParseValidators = new ArrayList<>();
    List<Validator<?>> postParseValidators = new ArrayList<>();
    Class<?> boxedParamType = methodParameter.parameterClass;
    if (methodParameter.parameterClass.isPrimitive()) {
        boxedParamType = box(methodParameter.parameterClass);
    }
    // Now we have an extractor, lets apply validators that are able to validate
    for (Annotation annotation : annotations) {
        WithValidator withValidator = annotation.annotationType().getAnnotation(WithValidator.class);
        if (withValidator != null) {
            Validator<?> validator = instantiateComponent(withValidator.value(), annotation, methodParameter.parameterClass, injector);
            // If the validator can validate the extractors type, then it's a pre parse validator
            if (validator.getValidatedType().isAssignableFrom(extractor.getExtractedType())) {
                preParseValidators.add(validator);
            // If it can validate the parameter type, it's a post parse validator
            } else if (validator.getValidatedType().isAssignableFrom(boxedParamType)) {
                postParseValidators.add(validator);
            // Otherwise, we can't validate with this validator
            } else {
                throw new RoutingException("Validator for field " + extractor.getFieldName() + " validates type " + validator.getValidatedType() + ", which doesn't match extracted type " + extractor.getExtractedType() + " or parameter type " + methodParameter.parameterClass);
            }
        }
    }
    // If we have pre parse validators, wrap our extractor in them
    if (!preParseValidators.isEmpty()) {
        extractor = new ValidatingArgumentExtractor(extractor, preParseValidators);
    }
    // String, and we can lookup a parser to parse it into the param type
    if (!boxedParamType.isAssignableFrom(extractor.getExtractedType())) {
        if (extractor.getFieldName() != null) {
            if (String.class.isAssignableFrom(extractor.getExtractedType())) {
                // Look up a parser for a single-valued parameter
                ParamParser<?> parser = injector.getInstance(ParamParsers.class).getParamParser(methodParameter.parameterClass);
                if (parser == null) {
                    throw new RoutingException("Can't find parameter parser for type " + extractor.getExtractedType() + " on field " + extractor.getFieldName());
                } else {
                    extractor = new ParsingArgumentExtractor(extractor, parser);
                }
            } else if (String[].class.isAssignableFrom(extractor.getExtractedType())) {
                // Look up a parser for a multi-valued parameter
                ArrayParamParser<?> parser = injector.getInstance(ParamParsers.class).getArrayParser(methodParameter.parameterClass);
                if (parser == null) {
                    throw new RoutingException("Can't find parameter array parser for type " + extractor.getExtractedType() + " on field " + extractor.getFieldName());
                } else {
                    extractor = new ParsingArrayExtractor(extractor, parser);
                }
            } else {
                throw new RoutingException("Extracted type " + extractor.getExtractedType() + " for field " + extractor.getFieldName() + " doesn't match parameter type " + methodParameter.parameterClass);
            }
        }
    }
    // If we have any post parse validators, wrap our extractor in them
    if (!postParseValidators.isEmpty()) {
        extractor = new ValidatingArgumentExtractor(extractor, postParseValidators);
    }
    if (methodParameter.isOptional) {
        extractor = new OptionalArgumentExtractor(extractor);
    }
    return extractor;
}
Also used : RoutingException(ninja.RoutingException) ArrayList(java.util.ArrayList) WithValidator(ninja.validation.WithValidator) Annotation(java.lang.annotation.Annotation) WithValidator(ninja.validation.WithValidator) Validator(ninja.validation.Validator) ArrayParamParser(ninja.params.ParamParsers.ArrayParamParser)

Aggregations

ArrayParamParser (ninja.params.ParamParsers.ArrayParamParser)2 Annotation (java.lang.annotation.Annotation)1 Field (java.lang.reflect.Field)1 ArrayList (java.util.ArrayList)1 Collection (java.util.Collection)1 List (java.util.List)1 RoutingException (ninja.RoutingException)1 ParamParser (ninja.params.ParamParser)1 ListParamParser (ninja.params.ParamParsers.ListParamParser)1 Validator (ninja.validation.Validator)1 WithValidator (ninja.validation.WithValidator)1