/** * * Invokes one of the resource methods annotated with {@link MethodMapping}. * * @param mappedMethod mapping info of the method. * @param attributes Attributes object for the current request. * @return the value returned by the invoked method */ private Object invokeMappedMethod(MethodMappingInfo mappedMethod, Attributes attributes) { Method method = mappedMethod.getMethod(); List parametersValues = new ArrayList(); // Attributes objects PageParameters pageParameters = attributes.getParameters(); WebResponse response = (WebResponse) attributes.getResponse(); HttpMethod httpMethod = HttpUtils.getHttpMethod((WebRequest) RequestCycle.get().getRequest()); LinkedHashMap<String, String> pathParameters = mappedMethod.populatePathParameters(pageParameters); Iterator<String> pathParamsIterator = pathParameters.values().iterator(); Class<?>[] parameterTypes = method.getParameterTypes(); for (int i = 0; i < parameterTypes.length; i++) { Object paramValue = null; MethodParameter methodParameter = new MethodParameter(parameterTypes[i], mappedMethod, i); Annotation annotation = ReflectionUtils.getAnnotationParam(i, method); // retrieve parameter value if (annotation != null) paramValue = extractParameterValue(methodParameter, pathParameters, annotation, pageParameters); else paramValue = extractParameterFromUrl(methodParameter, pathParamsIterator); // try to use the default value if (paramValue == null && !methodParameter.getDeaultValue().isEmpty()) paramValue = toObject(methodParameter.getParameterClass(), methodParameter.getDeaultValue()); if (paramValue == null && methodParameter.isRequired()) { response.sendError( 400, "No suitable method found for URL '" + extractUrlFromRequest() + "' and HTTP method " + httpMethod); return null; } parametersValues.add(paramValue); } try { return method.invoke(this, parametersValues.toArray()); } catch (Exception e) { response.sendError(500, "General server error."); throw new RuntimeException("Error invoking method '" + method.getName() + "'", e); } }
/** * * Handles a REST request invoking one of the methods annotated with {@link MethodMapping}. If * the annotated method returns a value, this latter is automatically serialized to a given string * format (like JSON, XML, etc...) and written to the web response.<br> * If no method is found to serve the current request, a 400 HTTP code is returned to the client. * Similarly, a 401 HTTP code is return if the user doesn't own one of the roles required to * execute an annotated method (See {@link AuthorizeInvocation}). */ @Override public final void respond(Attributes attributes) { PageParameters pageParameters = attributes.getParameters(); WebResponse response = (WebResponse) attributes.getResponse(); HttpMethod httpMethod = HttpUtils.getHttpMethod((WebRequest) RequestCycle.get().getRequest()); int indexedParamCount = pageParameters.getIndexedCount(); // mapped method are stored concatenating the number of the segments of // their URL and their HTTP method (see annotation MethodMapping) List<MethodMappingInfo> mappedMethodsCandidates = mappedMethods.get(indexedParamCount + "_" + httpMethod.getMethod()); MethodMappingInfo mappedMethod = selectMostSuitedMethod(mappedMethodsCandidates, pageParameters); if (mappedMethod != null) { if (!hasAny(mappedMethod.getRoles())) { response.sendError(401, "User is not allowed to invoke method on server."); return; } onBeforeMethodInvoked(mappedMethod, attributes); Object result = invokeMappedMethod(mappedMethod, attributes); onAfterMethodInvoked(mappedMethod, attributes, result); // if the invoked method returns a value, it is written to response if (result != null) { serializeObjectToResponse(response, result, mappedMethod.getMimeOutputFormat()); } } else { response.sendError( 400, "No suitable method found for URL '" + extractUrlFromRequest() + "' and HTTP method " + httpMethod); } }