ninja-core/src/main/java/ninja/params/ControllerMethodInvoker.java
public static ControllerMethodInvoker build(
            Method functionalMethod, 
            Method implementationMethod, 
            Injector injector,
            NinjaProperties ninjaProperties) {
        // get both the parameters...
        final Type[] genericParameterTypes = implementationMethod.getGenericParameterTypes();
        final MethodParameter[] methodParameters = MethodParameter.convertIntoMethodParameters(genericParameterTypes);
        // ... and all annotations for the parameters
        final Annotation[][] paramAnnotations = implementationMethod
                .getParameterAnnotations();

        ArgumentExtractor<?>[] argumentExtractors = new ArgumentExtractor<?>[methodParameters.length];

        // now we skip through the parameters and process the annotations
        for (int i = 0; i < methodParameters.length; i++) {
            try {
                argumentExtractors[i] = getArgumentExtractor(methodParameters[i], paramAnnotations[i],
                        injector);
            } catch (RoutingException e) {
                throw new RoutingException("Error building argument extractor for parameter " + i +
                        " in method " + implementationMethod.getDeclaringClass().getName() + "." + implementationMethod.getName() + "()", e);
            }
        }

        // Replace a null extractor with a bodyAs extractor, but make sure there's only one
        int bodyAsFound = -1;
        for (int i = 0; i < argumentExtractors.length; i++) {
            if (argumentExtractors[i] == null) {
                if (bodyAsFound > -1) {
                    throw new RoutingException("Only one parameter may be deserialised as the body "
                            + implementationMethod.getDeclaringClass().getName() + "." + implementationMethod.getName() + "()\n"
                            + "Extracted parameter is type: " + methodParameters[bodyAsFound].parameterClass.getName() + "\n"
                            + "Extra parmeter is type: " + methodParameters[i].parameterClass.getName());
                } else {
                    argumentExtractors[i] = new ArgumentExtractors.BodyAsExtractor(methodParameters[i].parameterClass);
                    bodyAsFound = i;
                }
            }
        }

        // Now that every parameter has an argument extractor we can run validation on the annotated
        // parameters
        for (int i = 0; i < argumentExtractors.length; i++) {
            argumentExtractors[i] =
                    validateArgumentWithExtractor(
                            methodParameters[i],
                            paramAnnotations[i], 
                            injector,
                            argumentExtractors[i]);
        }
        
        boolean useStrictArgumentExtractors = determineWhetherToUseStrictArgumentExtractorMode(ninjaProperties);

        return new ControllerMethodInvoker(functionalMethod, argumentExtractors, useStrictArgumentExtractors);
    }
public static ControllerMethodInvoker build(
            Method functionalMethod, 
            Method implementationMethod, 
            Injector injector,
            NinjaProperties ninjaProperties) {
        // get both the parameters...
        final Type[] genericParameterTypes = implementationMethod.getGenericParameterTypes();
        final MethodParameter[] methodParameters = MethodParameter.convertIntoMethodParameters(genericParameterTypes);
        // ... and all annotations for the parameters
        final Annotation[][] paramAnnotations = implementationMethod
                .getParameterAnnotations();

        ArgumentExtractor<?>[] argumentExtractors = new ArgumentExtractor<?>[methodParameters.length];

        // now we skip through the parameters and process the annotations
        for (int i = 0; i < methodParameters.length; i++) {
            try {
                argumentExtractors[i] = getArgumentExtractor(methodParameters[i], paramAnnotations[i],
                        injector);
            } catch (RoutingException e) {
                throw new RoutingException("Error building argument extractor for parameter " + i +
                        " in method " + implementationMethod.getDeclaringClass().getName() + "." + implementationMethod.getName() + "()", e);
            }
        }

        // Replace a null extractor with a bodyAs extractor, but make sure there's only one
        int bodyAsFound = -1;
        for (int i = 0; i < argumentExtractors.length; i++) {
            if (argumentExtractors[i] == null) {
                if (bodyAsFound > -1) {
                    throw new RoutingException("Only one parameter may be deserialised as the body "
                            + implementationMethod.getDeclaringClass().getName() + "." + implementationMethod.getName() + "()\n"
                            + "Extracted parameter is type: " + methodParameters[bodyAsFound].parameterClass.getName() + "\n"
                            + "Extra parmeter is type: " + methodParameters[i].parameterClass.getName());
                } else {
                    argumentExtractors[i] = new ArgumentExtractors.BodyAsExtractor(methodParameters[i].parameterClass);
                    bodyAsFound = i;
                }
            }
        }

        // Now that every parameter has an argument extractor we can run validation on the annotated
        // parameters
        for (int i = 0; i < argumentExtractors.length; i++) {
            argumentExtractors[i] =
                    validateArgumentWithExtractor(
                            methodParameters[i],
                            paramAnnotations[i], 
                            injector,
                            argumentExtractors[i]);
        }
        
        boolean useStrictArgumentExtractors = determineWhetherToUseStrictArgumentExtractorMode(ninjaProperties);

        return new ControllerMethodInvoker(functionalMethod, argumentExtractors, useStrictArgumentExtractors);
    }
public static ControllerMethodInvoker build ( Method functionalMethod , Method implementationMethod , Injector injector , NinjaProperties ninjaProperties ) { // get both the parameters... final Type [ ] genericParameterTypes = implementationMethod . getGenericParameterTypes ( ) ; final MethodParameter [ ] methodParameters = MethodParameter . convertIntoMethodParameters ( genericParameterTypes ) ; // ... and all annotations for the parameters final Annotation [ ] [ ] paramAnnotations = implementationMethod . getParameterAnnotations ( ) ; ArgumentExtractor < ? > [ ] argumentExtractors = new ArgumentExtractor < ? > [ methodParameters . length ] ; // now we skip through the parameters and process the annotations for ( int i = 0 ; i < methodParameters . length ; i ++ ) { try { argumentExtractors [ i ] = getArgumentExtractor ( methodParameters [ i ] , paramAnnotations [ i ] , injector ) ; } catch ( RoutingException e ) { throw new RoutingException ( "Error building argument extractor for parameter " + i + " in method " + implementationMethod . getDeclaringClass ( ) . getName ( ) + "." + implementationMethod . getName ( ) + "()" , e ) ; } } // Replace a null extractor with a bodyAs extractor, but make sure there's only one int bodyAsFound = - 1 ; for ( int i = 0 ; i < argumentExtractors . length ; i ++ ) { if ( argumentExtractors [ i ] == null ) { if ( bodyAsFound > - 1 ) { throw new RoutingException ( "Only one parameter may be deserialised as the body " + implementationMethod . getDeclaringClass ( ) . getName ( ) + "." + implementationMethod . getName ( ) + "()\n" + "Extracted parameter is type: " + methodParameters [ bodyAsFound ] . parameterClass . getName ( ) + "\n" + "Extra parmeter is type: " + methodParameters [ i ] . parameterClass . getName ( ) ) ; } else { argumentExtractors [ i ] = new ArgumentExtractors . BodyAsExtractor ( methodParameters [ i ] . parameterClass ) ; bodyAsFound = i ; } } } // Now that every parameter has an argument extractor we can run validation on the annotated // parameters for ( int i = 0 ; i < argumentExtractors . length ; i ++ ) { argumentExtractors [ i ] = validateArgumentWithExtractor ( methodParameters [ i ] , paramAnnotations [ i ] , injector , argumentExtractors [ i ] ) ; } boolean useStrictArgumentExtractors = determineWhetherToUseStrictArgumentExtractorMode ( ninjaProperties ) ; return new ControllerMethodInvoker ( functionalMethod , argumentExtractors , useStrictArgumentExtractors ) ; }
Builds an invoker for a functional method.  Understands what parameters
to inject and extract based on type and annotations.
@param functionalMethod The method to be invoked
@param implementationMethod The method to use for determining what
actual parameters and annotations to use for each argument.  Useful
when type/lambda erasure makes the functional interface not reliable
for reflecting.
@param injector The guice injector
@param ninjaProperties The NinjaProperties of this application
@return An invoker
Builds an invoker for a functional method . Understands what parameters to inject and extract based on type and annotations .