static play.mvc.Result invokeMethod( Class<?> targetClass, play.GlobalSettings global, Method method, Map<String, Object> extractedArgs, play.mvc.Http.RequestHeader r) { try { Object[] argValues = new Object[0]; List<Object> argVals = new ArrayList<Object>(); Annotation[][] annos = method.getParameterAnnotations(); for (Annotation[] ans : annos) { PathParam pathParam = null; QueryParam queryParam = null; for (Annotation an : ans) { if (an instanceof PathParam) pathParam = (PathParam) an; else if (an instanceof QueryParam) queryParam = (QueryParam) an; } if (pathParam != null) { Object v = extractedArgs.get(pathParam.value()); if (v != null) argVals.add(v); else throw new IllegalArgumentException( "can not find annotation value for argument " + pathParam.value() + "in " + targetClass + "#" + method); } else if (queryParam != null) { String queryString = r.getQueryString(queryParam.value()); argVals.add(queryString); // string type conversion? } else throw new IllegalArgumentException( "can not find an appropriate JAX-RC annotation for an argument for method:" + targetClass + "#" + method); } argValues = argVals.toArray(argValues); return (play.mvc.Result) method.invoke(global.getControllerInstance(targetClass), argValues); } catch (InvocationTargetException cause) { System.err.println( "Exception occured while trying to invoke: " + targetClass.getName() + "#" + method.getName() + " with " + extractedArgs + " for uri:" + r.path()); throw new RuntimeException(cause.getCause()); } catch (Exception e) { throw new RuntimeException(e.getCause()); } }
/** * Loads the overridden resource parameter values. * * @param signatureOverride The signature override. * @return The explicit resource parameters. */ protected List<ResourceParameter> loadResourceParameters( ResourceMethodSignature signatureOverride) { HashMap<String, String> paramComments = parseParamComments(getJavaDoc()); ArrayList<ResourceParameter> params = new ArrayList<ResourceParameter>(); for (CookieParam cookieParam : signatureOverride.cookieParams()) { params.add( new ExplicitResourceParameter( this, paramComments.get(cookieParam.value()), cookieParam.value(), ResourceParameterType.COOKIE)); } for (MatrixParam matrixParam : signatureOverride.matrixParams()) { params.add( new ExplicitResourceParameter( this, paramComments.get(matrixParam.value()), matrixParam.value(), ResourceParameterType.MATRIX)); } for (QueryParam queryParam : signatureOverride.queryParams()) { params.add( new ExplicitResourceParameter( this, paramComments.get(queryParam.value()), queryParam.value(), ResourceParameterType.QUERY)); } for (PathParam pathParam : signatureOverride.pathParams()) { params.add( new ExplicitResourceParameter( this, paramComments.get(pathParam.value()), pathParam.value(), ResourceParameterType.PATH)); } for (HeaderParam headerParam : signatureOverride.headerParams()) { params.add( new ExplicitResourceParameter( this, paramComments.get(headerParam.value()), headerParam.value(), ResourceParameterType.HEADER)); } for (FormParam formParam : signatureOverride.formParams()) { params.add( new ExplicitResourceParameter( this, paramComments.get(formParam.value()), formParam.value(), ResourceParameterType.FORM)); } return params; }
// CHECKSTYLE:OFF public static Parameter getParameter(int index, Annotation[] anns, Class<?> type) { Context ctx = AnnotationUtils.getAnnotation(anns, Context.class); if (ctx != null) { return new Parameter(ParameterType.CONTEXT, index, null); } boolean isEncoded = AnnotationUtils.getAnnotation(anns, Encoded.class) != null; BeanParam bp = AnnotationUtils.getAnnotation(anns, BeanParam.class); if (bp != null) { return new Parameter(ParameterType.BEAN, index, null, isEncoded, null); } String dValue = AnnotationUtils.getDefaultParameterValue(anns); PathParam a = AnnotationUtils.getAnnotation(anns, PathParam.class); if (a != null) { return new Parameter(ParameterType.PATH, index, a.value(), isEncoded, dValue); } QueryParam q = AnnotationUtils.getAnnotation(anns, QueryParam.class); if (q != null) { return new Parameter(ParameterType.QUERY, index, q.value(), isEncoded, dValue); } MatrixParam m = AnnotationUtils.getAnnotation(anns, MatrixParam.class); if (m != null) { return new Parameter(ParameterType.MATRIX, index, m.value(), isEncoded, dValue); } FormParam f = AnnotationUtils.getAnnotation(anns, FormParam.class); if (f != null) { return new Parameter(ParameterType.FORM, index, f.value(), isEncoded, dValue); } HeaderParam h = AnnotationUtils.getAnnotation(anns, HeaderParam.class); if (h != null) { return new Parameter(ParameterType.HEADER, index, h.value(), isEncoded, dValue); } CookieParam c = AnnotationUtils.getAnnotation(anns, CookieParam.class); if (c != null) { return new Parameter(ParameterType.COOKIE, index, c.value(), isEncoded, dValue); } return new Parameter(ParameterType.REQUEST_BODY, index, null); }
private void addMethodParameters(JaxrsResourceMethodDescription jaxrsRes, Method method) { for (Parameter param : method.getParameters()) { ParamInfo paramInfo = new ParamInfo(); paramInfo.cls = param.getType(); paramInfo.defaultValue = null; paramInfo.name = null; paramInfo.type = null; Annotation annotation; if ((annotation = param.getAnnotation(PathParam.class)) != null) { PathParam pathParam = (PathParam) annotation; paramInfo.name = pathParam.value(); paramInfo.type = "@" + PathParam.class.getSimpleName(); } else if ((annotation = param.getAnnotation(QueryParam.class)) != null) { QueryParam queryParam = (QueryParam) annotation; paramInfo.name = queryParam.value(); paramInfo.type = "@" + QueryParam.class.getSimpleName(); } else if ((annotation = param.getAnnotation(HeaderParam.class)) != null) { HeaderParam headerParam = (HeaderParam) annotation; paramInfo.name = headerParam.value(); paramInfo.type = "@" + HeaderParam.class.getSimpleName(); } else if ((annotation = param.getAnnotation(CookieParam.class)) != null) { CookieParam cookieParam = (CookieParam) annotation; paramInfo.name = cookieParam.value(); paramInfo.type = "@" + CookieParam.class.getSimpleName(); } else if ((annotation = param.getAnnotation(MatrixParam.class)) != null) { MatrixParam matrixParam = (MatrixParam) annotation; paramInfo.name = matrixParam.value(); paramInfo.type = "@" + MatrixParam.class.getSimpleName(); } else if ((annotation = param.getAnnotation(FormParam.class)) != null) { FormParam formParam = (FormParam) annotation; paramInfo.name = formParam.value(); paramInfo.type = "@" + FormParam.class.getSimpleName(); } if (paramInfo.name == null) { paramInfo.name = param.getName(); } if ((annotation = param.getAnnotation(DefaultValue.class)) != null) { DefaultValue defaultValue = (DefaultValue) annotation; paramInfo.defaultValue = defaultValue.value(); } jaxrsRes.parameters.add(paramInfo); } }
private void writeMethodImpl(JMethod method) throws UnableToCompleteException { boolean returnRequest = false; if (method.getReturnType() != JPrimitiveType.VOID) { if (!method.getReturnType().getQualifiedSourceName().equals(Request.class.getName()) && !method .getReturnType() .getQualifiedSourceName() .equals(JsonpRequest.class.getName())) { getLogger() .log( ERROR, "Invalid rest method. Method must have void, Request or JsonpRequest return types: " + method.getReadableDeclaration()); throw new UnableToCompleteException(); } else { returnRequest = true; } } Json jsonAnnotation = source.getAnnotation(Json.class); final Style classStyle = jsonAnnotation != null ? jsonAnnotation.style() : Style.DEFAULT; Options classOptions = source.getAnnotation(Options.class); Options options = method.getAnnotation(Options.class); p(method.getReadableDeclaration(false, false, false, false, true) + " {").i(1); { String restMethod = getRestMethod(method); LinkedList<JParameter> args = new LinkedList<JParameter>(Arrays.asList(method.getParameters())); // the last arg should be the callback. if (args.isEmpty()) { getLogger() .log( ERROR, "Invalid rest method. Method must declare at least a callback argument: " + method.getReadableDeclaration()); throw new UnableToCompleteException(); } JParameter callbackArg = args.removeLast(); JClassType callbackType = callbackArg.getType().isClassOrInterface(); JClassType methodCallbackType = METHOD_CALLBACK_TYPE; if (callbackType == null || !callbackType.isAssignableTo(methodCallbackType)) { getLogger() .log( ERROR, "Invalid rest method. Last argument must be a " + methodCallbackType.getName() + " type: " + method.getReadableDeclaration()); throw new UnableToCompleteException(); } JClassType resultType = getCallbackTypeGenericClass(callbackType); String pathExpression = null; Path pathAnnotation = method.getAnnotation(Path.class); if (pathAnnotation != null) { pathExpression = wrap(pathAnnotation.value()); } JParameter contentArg = null; HashMap<String, JParameter> queryParams = new HashMap<String, JParameter>(); HashMap<String, JParameter> formParams = new HashMap<String, JParameter>(); HashMap<String, JParameter> headerParams = new HashMap<String, JParameter>(); for (JParameter arg : args) { PathParam paramPath = arg.getAnnotation(PathParam.class); if (paramPath != null) { if (pathExpression == null) { getLogger() .log( ERROR, "Invalid rest method. Invalid @PathParam annotation. Method is missing the @Path annotation: " + method.getReadableDeclaration()); throw new UnableToCompleteException(); } pathExpression = pathExpression(pathExpression, arg, paramPath); // .replaceAll(Pattern.quote("{" + paramPath.value() + "}"), // "\"+com.google.gwt.http.client.URL.encodePathSegment(" + toStringExpression(arg) + // ")+\""); if (arg.getAnnotation(Attribute.class) != null) { // allow part of the arg-object participate in as PathParam and the object goes over the // wire contentArg = arg; } continue; } QueryParam queryParam = arg.getAnnotation(QueryParam.class); if (queryParam != null) { queryParams.put(queryParam.value(), arg); continue; } FormParam formParam = arg.getAnnotation(FormParam.class); if (formParam != null) { formParams.put(formParam.value(), arg); continue; } HeaderParam headerParam = arg.getAnnotation(HeaderParam.class); if (headerParam != null) { headerParams.put(headerParam.value(), arg); continue; } if (!formParams.isEmpty()) { getLogger() .log( ERROR, "You can not have both @FormParam parameters and a content parameter: " + method.getReadableDeclaration()); throw new UnableToCompleteException(); } if (contentArg != null) { getLogger() .log( ERROR, "Invalid rest method. Only one content parameter is supported: " + method.getReadableDeclaration()); throw new UnableToCompleteException(); } contentArg = arg; } String acceptTypeBuiltIn = null; if (callbackType.equals(TEXT_CALLBACK_TYPE)) { acceptTypeBuiltIn = "CONTENT_TYPE_TEXT"; } else if (callbackType.equals(JSON_CALLBACK_TYPE)) { acceptTypeBuiltIn = "CONTENT_TYPE_JSON"; } else if (callbackType.isAssignableTo(OVERLAY_CALLBACK_TYPE)) { acceptTypeBuiltIn = "CONTENT_TYPE_JSON"; } else if (callbackType.equals(XML_CALLBACK_TYPE)) { acceptTypeBuiltIn = "CONTENT_TYPE_XML"; } p("final " + METHOD_CLASS + " __method ="); p("getResource()"); if (pathExpression != null) { p(".resolve(" + pathExpression + ")"); } for (Map.Entry<String, JParameter> entry : queryParams.entrySet()) { String expr = entry.getValue().getName(); JClassType type = entry.getValue().getType().isClassOrInterface(); if (type != null && isQueryParamListType(type)) { p( ".addQueryParams(" + wrap(entry.getKey()) + ", " + toIteratedStringExpression(entry.getValue()) + ")"); } else { p( ".addQueryParam(" + wrap(entry.getKey()) + ", " + toStringExpression(entry.getValue().getType(), expr) + ")"); } } // example: .get() p("." + restMethod + "();"); // Handle JSONP specific configuration... JSONP jsonpAnnotation = method.getAnnotation(JSONP.class); final boolean isJsonp = restMethod.equals(METHOD_JSONP) && jsonpAnnotation != null; if (isJsonp) { if (returnRequest && !method .getReturnType() .getQualifiedSourceName() .equals(JsonpRequest.class.getName())) { getLogger() .log( ERROR, "Invalid rest method. JSONP method must have void or JsonpRequest return types: " + method.getReadableDeclaration()); throw new UnableToCompleteException(); } if (jsonpAnnotation.callbackParam().length() > 0) { p( "((" + JSONP_METHOD_CLASS + ")__method).callbackParam(" + wrap(jsonpAnnotation.callbackParam()) + ");"); } if (jsonpAnnotation.failureCallbackParam().length() > 0) { p( "((" + JSONP_METHOD_CLASS + ")__method).failureCallbackParam(" + wrap(jsonpAnnotation.failureCallbackParam()) + ");"); } } else { if (returnRequest && !method.getReturnType().getQualifiedSourceName().equals(Request.class.getName())) { getLogger() .log( ERROR, "Invalid rest method. Non JSONP method must have void or Request return types: " + method.getReadableDeclaration()); throw new UnableToCompleteException(); } } // configure the dispatcher if (options != null && options.dispatcher() != Dispatcher.class) { // use the dispatcher configured for the method. p("__method.setDispatcher(" + options.dispatcher().getName() + ".INSTANCE);"); } else { // use the default dispatcher configured for the service.. p("__method.setDispatcher(this.dispatcher);"); } // configure the expected statuses.. if (options != null && options.expect().length != 0) { // Using method level defined expected status p("__method.expect(" + join(options.expect(), ", ") + ");"); } else if (classOptions != null && classOptions.expect().length != 0) { // Using class level defined expected status p("__method.expect(" + join(classOptions.expect(), ", ") + ");"); } // configure the timeout if (options != null && options.timeout() >= 0) { // Using method level defined value p("__method.timeout(" + options.timeout() + ");"); } else if (classOptions != null && classOptions.timeout() >= 0) { // Using class level defined value p("__method.timeout(" + classOptions.timeout() + ");"); } if (jsonpAnnotation == null) { Produces producesAnnotation = findAnnotationOnMethodOrEnclosingType(method, Produces.class); if (producesAnnotation != null) { p( "__method.header(" + RESOURCE_CLASS + ".HEADER_ACCEPT, " + wrap(producesAnnotation.value()[0]) + ");"); } else { // set the default accept header.... if (acceptTypeBuiltIn != null) { p( "__method.header(" + RESOURCE_CLASS + ".HEADER_ACCEPT, " + RESOURCE_CLASS + "." + acceptTypeBuiltIn + ");"); } else { p( "__method.header(" + RESOURCE_CLASS + ".HEADER_ACCEPT, " + RESOURCE_CLASS + ".CONTENT_TYPE_JSON);"); } } Consumes consumesAnnotation = findAnnotationOnMethodOrEnclosingType(method, Consumes.class); if (consumesAnnotation != null) { p( "__method.header(" + RESOURCE_CLASS + ".HEADER_CONTENT_TYPE, " + wrap(consumesAnnotation.value()[0]) + ");"); } // and set the explicit headers now (could override the accept header) for (Map.Entry<String, JParameter> entry : headerParams.entrySet()) { String expr = entry.getValue().getName(); p( "__method.header(" + wrap(entry.getKey()) + ", " + toStringExpression(entry.getValue().getType(), expr) + ");"); } } if (!formParams.isEmpty()) { p(FORM_POST_CONTENT_CLASS + " __formPostContent = new " + FORM_POST_CONTENT_CLASS + "();"); for (Map.Entry<String, JParameter> entry : formParams.entrySet()) { p( "__formPostContent.addParameter(" + wrap(entry.getKey()) + ", " + toFormStringExpression(entry.getValue(), classStyle) + ");"); } p("__method.form(__formPostContent.getTextContent());"); } if (contentArg != null) { if (contentArg.getType() == STRING_TYPE) { p("__method.text(" + contentArg.getName() + ");"); } else if (contentArg.getType() == JSON_VALUE_TYPE) { p("__method.json(" + contentArg.getName() + ");"); } else if (contentArg.getType().isClass() != null && isOverlayArrayType(contentArg.getType().isClass())) { p("__method.json(new " + JSON_ARRAY_CLASS + "(" + contentArg.getName() + "));"); } else if (contentArg.getType().isClass() != null && contentArg.getType().isClass().isAssignableTo(OVERLAY_VALUE_TYPE)) { p("__method.json(new " + JSON_OBJECT_CLASS + "(" + contentArg.getName() + "));"); } else if (contentArg.getType() == DOCUMENT_TYPE) { p("__method.xml(" + contentArg.getName() + ");"); } else { JClassType contentClass = contentArg.getType().isClass(); if (contentClass == null) { contentClass = contentArg.getType().isClassOrInterface(); if (!locator.isCollectionType(contentClass)) { getLogger().log(ERROR, "Content argument must be a class."); throw new UnableToCompleteException(); } } jsonAnnotation = contentArg.getAnnotation(Json.class); Style style = jsonAnnotation != null ? jsonAnnotation.style() : classStyle; // example: // .json(Listings$_Generated_JsonEncoder_$.INSTANCE.encode(arg0) // ) p( "__method.json(" + locator.encodeExpression(contentClass, contentArg.getName(), style) + ");"); } } List<AnnotationResolver> annotationResolvers = getAnnotationResolvers(context, getLogger()); getLogger() .log( TreeLogger.DEBUG, "found " + annotationResolvers.size() + " additional AnnotationResolvers"); for (AnnotationResolver a : annotationResolvers) { getLogger() .log( TreeLogger.DEBUG, "(" + a.getClass().getName() + ") resolve `" + source.getName() + "#" + method.getName() + "´ ..."); final Map<String, String[]> addDataParams = a.resolveAnnotation(getLogger(), source, method, restMethod); if (addDataParams != null) { for (String s : addDataParams.keySet()) { final StringBuilder sb = new StringBuilder(); final List<String> classList = Arrays.asList(addDataParams.get(s)); sb.append("["); for (int i = 0; i < classList.size(); ++i) { sb.append("\\\"").append(classList.get(i)).append("\\\""); if ((i + 1) < classList.size()) { sb.append(","); } } sb.append("]"); getLogger() .log(TreeLogger.DEBUG, "add call with (\"" + s + "\", \"" + sb.toString() + "\")"); p("__method.addData(\"" + s + "\", \"" + sb.toString() + "\");"); } } } if (acceptTypeBuiltIn != null) { // TODO: shouldn't we also have a cach in here? p(returnRequest(returnRequest, isJsonp) + "__method.send(" + callbackArg.getName() + ");"); } else if (isJsonp) { p(returnRequest(returnRequest, isJsonp) + "((" + JSONP_METHOD_CLASS + ")__method).send(new " + ABSTRACT_ASYNC_CALLBACK_CLASS + "<" + resultType.getParameterizedQualifiedSourceName() + ">((" + JSONP_METHOD_CLASS + ")__method, " + callbackArg.getName() + ") {") .i(1); { p("protected " + resultType.getParameterizedQualifiedSourceName() + " parseResult(" + JSON_VALUE_CLASS + " result) throws Exception {") .i(1); { if (resultType.getParameterizedQualifiedSourceName().equals("java.lang.Void")) { p("return (java.lang.Void) null;"); } else { p("try {").i(1); { if (resultType.isAssignableTo(locator.LIST_TYPE)) { p("result = new " + JSON_ARRAY_CLASS + "(result.getJavaScriptObject());"); } jsonAnnotation = method.getAnnotation(Json.class); Style style = jsonAnnotation != null ? jsonAnnotation.style() : classStyle; p("return " + locator.decodeExpression(resultType, "result", style) + ";"); } i(-1).p("} catch (Throwable __e) {").i(1); { p( "throw new " + RESPONSE_FORMAT_EXCEPTION_CLASS + "(\"Response was NOT a valid JSON document\", __e);"); } i(-1).p("}"); } } i(-1).p("}"); } i(-1).p("});"); } else { p("try {").i(1); { p(returnRequest(returnRequest, isJsonp) + "__method.send(new " + ABSTRACT_REQUEST_CALLBACK_CLASS + "<" + resultType.getParameterizedQualifiedSourceName() + ">(__method, " + callbackArg.getName() + ") {") .i(1); { p("protected " + resultType.getParameterizedQualifiedSourceName() + " parseResult() throws Exception {") .i(1); { if (resultType.getParameterizedQualifiedSourceName().equals("java.lang.Void")) { p("return (java.lang.Void) null;"); } else { p("try {").i(1); { jsonAnnotation = method.getAnnotation(Json.class); Style style = jsonAnnotation != null ? jsonAnnotation.style() : classStyle; p( "return " + locator.decodeExpression( resultType, JSON_PARSER_CLASS + ".parse(__method.getResponse().getText())", style) + ";"); } i(-1).p("} catch (Throwable __e) {").i(1); { p( "throw new " + RESPONSE_FORMAT_EXCEPTION_CLASS + "(\"Response was NOT a valid JSON document\", __e);"); } i(-1).p("}"); } } i(-1).p("}"); } i(-1).p("});"); } i(-1).p("} catch (" + REQUEST_EXCEPTION_CLASS + " __e) {").i(1); { p(callbackArg.getName() + ".onFailure(__method,__e);"); if (returnRequest) { p("return null;"); } } i(-1).p("}"); } } i(-1).p("}"); }
public T fromAnnotations() { Annotation[] annotations = parameter.getAnnotations(); AccessibleObject injectTarget = parameter.getAccessibleObject(); Class<?> type = parameter.getResourceClass().getClazz(); parameter.encoded = findAnnotation(annotations, Encoded.class) != null || injectTarget.isAnnotationPresent(Encoded.class) || type.isAnnotationPresent(Encoded.class); DefaultValue defaultValue = findAnnotation(annotations, DefaultValue.class); if (defaultValue != null) parameter.defaultValue = defaultValue.value(); QueryParam query; HeaderParam header; MatrixParam matrix; PathParam uriParam; CookieParam cookie; FormParam formParam; Form form; Suspend suspend; Suspended suspended; if ((query = findAnnotation(annotations, QueryParam.class)) != null) { parameter.paramType = Parameter.ParamType.QUERY_PARAM; parameter.paramName = query.value(); } else if ((header = findAnnotation(annotations, HeaderParam.class)) != null) { parameter.paramType = Parameter.ParamType.HEADER_PARAM; parameter.paramName = header.value(); } else if ((formParam = findAnnotation(annotations, FormParam.class)) != null) { parameter.paramType = Parameter.ParamType.FORM_PARAM; parameter.paramName = formParam.value(); } else if ((cookie = findAnnotation(annotations, CookieParam.class)) != null) { parameter.paramType = Parameter.ParamType.COOKIE_PARAM; parameter.paramName = cookie.value(); } else if ((uriParam = findAnnotation(annotations, PathParam.class)) != null) { parameter.paramType = Parameter.ParamType.PATH_PARAM; parameter.paramName = uriParam.value(); } else if ((form = findAnnotation(annotations, Form.class)) != null) { parameter.paramType = Parameter.ParamType.FORM; parameter.paramName = form.prefix(); } else if (findAnnotation(annotations, BeanParam.class) != null) { parameter.paramType = Parameter.ParamType.BEAN_PARAM; } else if ((matrix = findAnnotation(annotations, MatrixParam.class)) != null) { parameter.paramType = Parameter.ParamType.MATRIX_PARAM; parameter.paramName = matrix.value(); } else if ((suspend = findAnnotation(annotations, Suspend.class)) != null) { parameter.paramType = Parameter.ParamType.SUSPEND; parameter.suspendTimeout = suspend.value(); } else if (findAnnotation(annotations, Context.class) != null) { parameter.paramType = Parameter.ParamType.CONTEXT; } else if ((suspended = findAnnotation(annotations, Suspended.class)) != null) { parameter.paramType = Parameter.ParamType.SUSPENDED; } else if (javax.ws.rs.container.AsyncResponse.class.isAssignableFrom(type)) { parameter.paramType = Parameter.ParamType.SUSPENDED; } else if (findAnnotation(annotations, Body.class) != null) { parameter.paramType = Parameter.ParamType.MESSAGE_BODY; } else { parameter.paramType = Parameter.ParamType.UNKNOWN; } return (T) this; }
private void writeMethodImpl(JMethod method) throws UnableToCompleteException { if (method.getReturnType().isPrimitive() != JPrimitiveType.VOID) { error( "Invalid rest method. Method must have void return type: " + method.getReadableDeclaration()); } Json jsonAnnotation = source.getAnnotation(Json.class); final Style classStyle = jsonAnnotation != null ? jsonAnnotation.style() : Style.DEFAULT; Options classOptions = source.getAnnotation(Options.class); Options options = method.getAnnotation(Options.class); p(method.getReadableDeclaration(false, false, false, false, true) + " {").i(1); { String restMethod = getRestMethod(method); LinkedList<JParameter> args = new LinkedList<JParameter>(Arrays.asList(method.getParameters())); // the last arg should be the callback. if (args.isEmpty()) { error( "Invalid rest method. Method must declare at least a callback argument: " + method.getReadableDeclaration()); } JParameter callbackArg = args.removeLast(); JClassType callbackType = callbackArg.getType().isClassOrInterface(); JClassType methodCallbackType = METHOD_CALLBACK_TYPE; if (callbackType == null || !callbackType.isAssignableTo(methodCallbackType)) { error( "Invalid rest method. Last argument must be a " + methodCallbackType.getName() + " type: " + method.getReadableDeclaration()); } JClassType resultType = getCallbackTypeGenericClass(callbackType); String pathExpression = null; Path pathAnnotation = method.getAnnotation(Path.class); if (pathAnnotation != null) { pathExpression = wrap(pathAnnotation.value()); } JParameter contentArg = null; HashMap<String, JParameter> queryParams = new HashMap<String, JParameter>(); HashMap<String, JParameter> headerParams = new HashMap<String, JParameter>(); for (JParameter arg : args) { PathParam paramPath = arg.getAnnotation(PathParam.class); if (paramPath != null) { if (pathExpression == null) { error( "Invalid rest method. Invalid @PathParam annotation. Method is missing the @Path annotation: " + method.getReadableDeclaration()); } pathExpression = pathExpression.replaceAll( Pattern.quote("{" + paramPath.value() + "}"), "\"+" + toStringExpression(arg) + "+\""); continue; } QueryParam queryParam = arg.getAnnotation(QueryParam.class); if (queryParam != null) { queryParams.put(queryParam.value(), arg); continue; } HeaderParam headerParam = arg.getAnnotation(HeaderParam.class); if (headerParam != null) { headerParams.put(headerParam.value(), arg); continue; } if (contentArg != null) { error( "Invalid rest method. Only one content parameter is supported: " + method.getReadableDeclaration()); } contentArg = arg; } String acceptTypeBuiltIn = null; if (callbackType.equals(TEXT_CALLBACK_TYPE)) { acceptTypeBuiltIn = "CONTENT_TYPE_TEXT"; } else if (callbackType.equals(JSON_CALLBACK_TYPE)) { acceptTypeBuiltIn = "CONTENT_TYPE_JSON"; } else if (callbackType.isAssignableTo(OVERLAY_CALLBACK_TYPE)) { acceptTypeBuiltIn = "CONTENT_TYPE_JSON"; } else if (callbackType.equals(XML_CALLBACK_TYPE)) { acceptTypeBuiltIn = "CONTENT_TYPE_XML"; } p("final " + METHOD_CLASS + " __method ="); p("this.resource"); if (pathExpression != null) { p(".resolve(" + pathExpression + ")"); } for (Map.Entry<String, JParameter> entry : queryParams.entrySet()) { String expr = entry.getValue().getName(); p( ".addQueryParam(" + wrap(entry.getKey()) + ", " + toStringExpression(entry.getValue().getType(), expr) + ")"); } // example: .get() p("." + restMethod + "();"); // Handle JSONP specific configuration... JSONP jsonpAnnotation = method.getAnnotation(JSONP.class); if (restMethod.equals(METHOD_JSONP) && jsonpAnnotation != null) { if (jsonpAnnotation.callbackParam().length() > 0) { p( "((" + JSONP_METHOD_CLASS + ")__method).callbackParam(" + wrap(jsonpAnnotation.callbackParam()) + ");"); } if (jsonpAnnotation.failureCallbackParam().length() > 0) { p( "((" + JSONP_METHOD_CLASS + ")__method).failureCallbackParam(" + wrap(jsonpAnnotation.failureCallbackParam()) + ");"); } } // configure the dispatcher if (options != null && options.dispatcher() != Dispatcher.class) { // use the dispatcher configured for the method. p("__method.setDispatcher(" + options.dispatcher().getName() + ".INSTANCE);"); } else { // use the default dispatcher configured for the service.. p("__method.setDispatcher(this.dispatcher);"); } // configure the expected statuses.. if (options != null && options.expect().length != 0) { // Using method level defined expected status p("__method.expect(" + join(options.expect(), ", ") + ");"); } else if (classOptions != null && classOptions.expect().length != 0) { // Using class level defined expected status p("__method.expect(" + join(classOptions.expect(), ", ") + ");"); } // configure the timeout if (options != null && options.timeout() >= 0) { // Using method level defined value p("__method.timeout(" + options.timeout() + ");"); } else if (classOptions != null && classOptions.timeout() >= 0) { // Using class level defined value p("__method.timeout(" + classOptions.timeout() + ");"); } Produces producesAnnotation = findAnnotationOnMethodOrEnclosingType(method, Produces.class); if (producesAnnotation != null) { p( "__method.header(" + RESOURCE_CLASS + ".HEADER_ACCEPT, " + wrap(producesAnnotation.value()[0]) + ");"); } else { // set the default accept header.... if (acceptTypeBuiltIn != null) { p( "__method.header(" + RESOURCE_CLASS + ".HEADER_ACCEPT, " + RESOURCE_CLASS + "." + acceptTypeBuiltIn + ");"); } else { p( "__method.header(" + RESOURCE_CLASS + ".HEADER_ACCEPT, " + RESOURCE_CLASS + ".CONTENT_TYPE_JSON);"); } } Consumes consumesAnnotation = findAnnotationOnMethodOrEnclosingType(method, Consumes.class); if (consumesAnnotation != null) { p( "__method.header(" + RESOURCE_CLASS + ".HEADER_CONTENT_TYPE, " + wrap(consumesAnnotation.value()[0]) + ");"); } // and set the explicit headers now (could override the accept header) for (Map.Entry<String, JParameter> entry : headerParams.entrySet()) { String expr = entry.getValue().getName(); p( "__method.header(" + wrap(entry.getKey()) + ", " + toStringExpression(entry.getValue().getType(), expr) + ");"); } if (contentArg != null) { if (contentArg.getType() == STRING_TYPE) { p("__method.text(" + contentArg.getName() + ");"); } else if (contentArg.getType() == JSON_VALUE_TYPE) { p("__method.json(" + contentArg.getName() + ");"); } else if (contentArg.getType().isClass() != null && isOverlayArrayType(contentArg.getType().isClass())) { p("__method.json(new " + JSON_ARRAY_CLASS + "(" + contentArg.getName() + "));"); } else if (contentArg.getType().isClass() != null && contentArg.getType().isClass().isAssignableTo(OVERLAY_VALUE_TYPE)) { p("__method.json(new " + JSON_OBJECT_CLASS + "(" + contentArg.getName() + "));"); } else if (contentArg.getType() == DOCUMENT_TYPE) { p("__method.xml(" + contentArg.getName() + ");"); } else { JClassType contentClass = contentArg.getType().isClass(); if (contentClass == null) { error("Content argument must be a class."); } jsonAnnotation = contentArg.getAnnotation(Json.class); Style style = jsonAnnotation != null ? jsonAnnotation.style() : classStyle; // example: // .json(Listings$_Generated_JsonEncoder_$.INSTANCE.encode(arg0) // ) p( "__method.json(" + locator.encodeExpression(contentClass, contentArg.getName(), style) + ");"); } } if (acceptTypeBuiltIn != null) { p("__method.send(" + callbackArg.getName() + ");"); } else { p("try {").i(1); { p("__method.send(new " + ABSTRACT_REQUEST_CALLBACK_CLASS + "<" + resultType.getParameterizedQualifiedSourceName() + ">(__method, " + callbackArg.getName() + ") {") .i(1); { p("protected " + resultType.getParameterizedQualifiedSourceName() + " parseResult() throws Exception {") .i(1); { if (resultType.getParameterizedQualifiedSourceName().equals("java.lang.Void")) { p("return (java.lang.Void) new java.lang.Object();"); } else { p("try {").i(1); { jsonAnnotation = method.getAnnotation(Json.class); Style style = jsonAnnotation != null ? jsonAnnotation.style() : classStyle; p( "return " + locator.decodeExpression( resultType, JSON_PARSER_CLASS + ".parse(__method.getResponse().getText())", style) + ";"); } i(-1).p("} catch (Throwable __e) {").i(1); { p( "throw new " + RESPONSE_FORMAT_EXCEPTION_CLASS + "(\"Response was NOT a valid JSON document\", __e);"); } i(-1).p("}"); } } i(-1).p("}"); } i(-1).p("});"); } i(-1).p("} catch (" + REQUEST_EXCEPTION_CLASS + " __e) {").i(1); { p(callbackArg.getName() + ".onFailure(__method,__e);"); } i(-1).p("}"); } } i(-1).p("}"); }
private Object[] assemParams(Class<?>[] paramTypes, Annotation[][] paramAnns) throws Exception { Object[] params = new Object[paramTypes.length]; int pathParamIndex = 0; for (int i = 0; i < paramTypes.length; ++i) { Annotation[] anns = paramAnns[i]; Class<?> paramClass = paramTypes[i]; String[] paramValue = null; // ------------------------------------------------------ // 通过给定class 获取对应的ActionContextObj if (Context.class.isAssignableFrom(paramClass)) { params[i] = this.context; continue; } if (HttpServletRequest.class.isAssignableFrom(paramClass)) { params[i] = this.context.getRequest(); continue; } if (HttpServletResponse.class.isAssignableFrom(paramClass)) { params[i] = this.context.getResponse(); continue; } if (PrintWriter.class.isAssignableFrom(paramClass)) { params[i] = this.context.getWriter(); continue; } if (ServletOutputStream.class.isAssignableFrom(paramClass)) { params[i] = this.context.getOut(); continue; } if (HttpSession.class.isAssignableFrom(paramClass)) { params[i] = this.context.getSession(); continue; } if (ActionProp.class.isAssignableFrom(paramClass)) { if (this.context.getActionProp() == null) this.context.setActionProp(new ActionProp(this.actionObject.getClass().getName())); params[i] = this.context.getActionProp(); continue; } if (Validation.class.isAssignableFrom(paramClass)) { params[i] = this.context.getValidation(); continue; } if (QueryParams.class.isAssignableFrom(paramClass)) { params[i] = this.context.getQueryParams(); continue; } if (DAO.class.isAssignableFrom(paramClass)) { params[i] = new DAOImpl(""); continue; } if (InsertDAO.class.isAssignableFrom(paramClass)) { params[i] = DAOFactory.getInsertDAO(); continue; } if (DeleteDAO.class.isAssignableFrom(paramClass)) { params[i] = DAOFactory.getDeleteDAO(); continue; } if (UpdateDAO.class.isAssignableFrom(paramClass)) { params[i] = DAOFactory.getUpdateDAO(); continue; } if (SelectDAO.class.isAssignableFrom(paramClass)) { params[i] = DAOFactory.getSelectDAO(); continue; } if (DivPageDAO.class.isAssignableFrom(paramClass)) { params[i] = DAOFactory.getDivPageDAO(); continue; } if (SearchDAO.class.isAssignableFrom(paramClass)) { params[i] = DAOFactory.getSearchDAO(); continue; } if (CascadeDAO.class.isAssignableFrom(paramClass)) { params[i] = DAOFactory.getCascadeDAO(); continue; } PathParam pathParamAnn = this.getPathParamAnn(anns); if (pathParamAnn != null) { paramValue = this.getPathParamValue(pathParamAnn.value()); params[i] = ClassUtil.getParamVal(paramClass, paramValue[0]); continue; } QueryParam queryParamAnn = this.getQueryParamAnn(anns); // 视图模型 if (queryParamAnn == null && Map.class.isAssignableFrom(paramClass)) { params[i] = this.context.getModel(); continue; } if (queryParamAnn != null) { final String fieldName = queryParamAnn.value(); if (File.class.isAssignableFrom(paramClass)) { if (!this.context.getUploadMap().containsKey(fieldName)) continue; List<UploadFile> list = this.context.getUploadMap().get(fieldName); if (list == null || list.isEmpty()) continue; UploadFile uploadFile = list.get(0); File file = uploadFile.getTmpFile(); params[i] = file; continue; } if (File[].class.isAssignableFrom(paramClass)) { if (!this.context.getUploadMap().containsKey(fieldName)) continue; List<UploadFile> list = this.context.getUploadMap().get(fieldName); if (list == null || list.isEmpty()) continue; File[] files = new File[list.size()]; for (int j = 0; j < files.length; j++) files[j] = list.get(j).getTmpFile(); params[i] = files; } if (UploadFile.class.isAssignableFrom(paramClass)) { if (!this.context.getUploadMap().containsKey(fieldName)) continue; List<UploadFile> list = this.context.getUploadMap().get(fieldName); if (list == null || list.isEmpty()) continue; UploadFile uploadFile = list.get(0); params[i] = uploadFile; continue; } if (UploadFile[].class.isAssignableFrom(paramClass)) { if (!this.context.getUploadMap().containsKey(fieldName)) continue; List<UploadFile> list = this.context.getUploadMap().get(fieldName); if (list == null || list.isEmpty()) continue; params[i] = list.toArray(new UploadFile[] {}); } String defaultValue = null; DefaultValue defaultValueAnn = this.getDefaultValueAnn(anns); if (defaultValueAnn != null) defaultValue = defaultValueAnn.value(); paramValue = this.getQueryParamValue(fieldName, defaultValue); if (java.util.Date.class.isAssignableFrom(paramClass)) { params[i] = this.getDateParam(anns, paramValue[0]); continue; } String startName = fieldName; if (ClassUtil.isPojo(paramClass)) { params[i] = this.injectParam2Pojo(paramClass, startName); continue; } if (Map.class.isAssignableFrom(paramClass)) { params[i] = this.injectParam2Map(startName); continue; } if (paramClass.isArray()) params[i] = ClassUtil.getParamVals(paramClass, paramValue); else params[i] = ClassUtil.getParamVal(paramClass, paramValue[0]); } else { // 如果是基本数据类型,则按照排序进行注入 String[] pathParams = this.context.getActionConfigBean().getPathParams(); if (pathParams == null) { log.warn("QueryParam not found and PathParam not found too"); continue; } paramValue = this.getPathParamValue(pathParams[pathParamIndex]); params[i] = ClassUtil.getParamVal(paramClass, paramValue[0]); pathParamIndex++; continue; } } return params; }