Permalink
Browse files

* support @QueryParam, @CookieParam, @HeaderParam JSR-311 annotations

in ERRest
    * support primitives in annotated parameters
  • Loading branch information...
1 parent 4b7f997 commit a7b17896ac46a794679ef161fa2b7ebe41a7e7c0 @mschrag mschrag committed May 16, 2011
@@ -146,7 +146,32 @@ protected static String dateFormat(boolean spaces) {
public static Object coerceValueToTypeNamed(Object value, String valueTypeName, IERXRestDelegate delegate) {
Object parsedValue;
Class<?> valueType = _NSUtilities.classWithName(valueTypeName);
- if (ERXValueUtilities.isNull(value)) {
+ // test primitives first, since we can't return a null for them
+ if (valueType != null && int.class.isAssignableFrom(valueType)) {
+ parsedValue = ERXValueUtilities.intValueWithDefault(value, 0);
+ }
+ else if (valueType != null && boolean.class.isAssignableFrom(valueType)) {
+ parsedValue = ERXValueUtilities.booleanValueWithDefault(value, false);
+ }
+ else if (valueType != null && char.class.isAssignableFrom(valueType)) {
+ parsedValue = (char)ERXValueUtilities.intValueWithDefault(value, 0);
+ }
+ else if (valueType != null && byte.class.isAssignableFrom(valueType)) {
+ parsedValue = (byte)ERXValueUtilities.intValueWithDefault(value, 0);
+ }
+ else if (valueType != null && long.class.isAssignableFrom(valueType)) {
+ parsedValue = ERXValueUtilities.longValueWithDefault(value, 0);
+ }
+ else if (valueType != null && float.class.isAssignableFrom(valueType)) {
+ parsedValue = ERXValueUtilities.floatValueWithDefault(value, 0);
+ }
+ else if (valueType != null && double.class.isAssignableFrom(valueType)) {
+ parsedValue = ERXValueUtilities.doubleValueWithDefault(value, 0);
+ }
+ else if (valueType != null && short.class.isAssignableFrom(valueType)) {
+ parsedValue = (short)ERXValueUtilities.intValueWithDefault(value, 0);
+ }
+ else if (ERXValueUtilities.isNull(value)) {
parsedValue = null;
}
else if (valueType != null && String.class.isAssignableFrom(valueType)) {
@@ -47,14 +47,18 @@
import er.rest.ERXRestClassDescriptionFactory;
import er.rest.ERXRestFetchSpecification;
import er.rest.ERXRestRequestNode;
+import er.rest.ERXRestUtils;
import er.rest.IERXRestDelegate;
import er.rest.format.ERXRestFormat;
import er.rest.format.ERXWORestRequest;
import er.rest.format.ERXWORestResponse;
import er.rest.format.IERXRestParser;
+import er.rest.routes.jsr311.CookieParam;
+import er.rest.routes.jsr311.HeaderParam;
import er.rest.routes.jsr311.Path;
import er.rest.routes.jsr311.PathParam;
import er.rest.routes.jsr311.Paths;
+import er.rest.routes.jsr311.QueryParam;
import er.rest.util.ERXRestSchema;
import er.rest.util.ERXRestTransactionRequestAdaptor;
@@ -1323,7 +1327,7 @@ public WOActionResults performActionNamed(String actionName, boolean throwExcept
if (actionMethod == null || actionMethod.getParameterTypes().length > 0) {
int bestParameterCount = 0;
Method bestMethod = null;
- List<PathParam> bestParams = null;
+ List<Annotation> bestParams = null;
for (Method method : getClass().getDeclaredMethods()) {
String methodName = method.getName();
boolean nameMatches = methodName.equals(actionMethodName);
@@ -1332,12 +1336,11 @@ public WOActionResults performActionNamed(String actionName, boolean throwExcept
}
if (nameMatches) {
int parameterCount = 0;
- List<PathParam> params = new LinkedList<PathParam>();
+ List<Annotation> params = new LinkedList<Annotation>();
for (Annotation[] parameterAnnotations : method.getParameterAnnotations()) {
for (Annotation parameterAnnotation : parameterAnnotations) {
- if (parameterAnnotation instanceof PathParam) {
- PathParam pathParam = (PathParam)parameterAnnotation;
- params.add(pathParam);
+ if (parameterAnnotation instanceof PathParam || parameterAnnotation instanceof QueryParam || parameterAnnotation instanceof CookieParam || parameterAnnotation instanceof HeaderParam) {
+ params.add(parameterAnnotation);
parameterCount ++;
}
else {
@@ -1360,10 +1363,28 @@ public WOActionResults performActionNamed(String actionName, boolean throwExcept
performUnknownAction(actionName);
}
else {
+ Class<?>[] parameterTypes = bestMethod.getParameterTypes();
Object[] params = new Object[bestParameterCount];
for (int paramNum = 0; paramNum < params.length; paramNum ++) {
- PathParam param = bestParams.get(paramNum);
- params[paramNum] = routeObjectForKey(param.value());
+ Annotation param = bestParams.get(paramNum);
+ if (param instanceof PathParam) {
+ params[paramNum] = routeObjectForKey(((PathParam)param).value());
+ }
+ else if (param instanceof QueryParam) {
+ String value = request().stringFormValueForKey(((QueryParam)param).value());
+ params[paramNum] = ERXRestUtils.coerceValueToTypeNamed(value, parameterTypes[paramNum].getName(), delegate());
+ }
+ else if (param instanceof CookieParam) {
+ String value = request().cookieValueForKey(((CookieParam)param).value());
+ params[paramNum] = ERXRestUtils.coerceValueToTypeNamed(value, parameterTypes[paramNum].getName(), delegate());
+ }
+ else if (param instanceof HeaderParam) {
+ String value = request().headerForKey(((HeaderParam)param).value());
+ params[paramNum] = ERXRestUtils.coerceValueToTypeNamed(value, parameterTypes[paramNum].getName(), delegate());
+ }
+ else {
+ throw new IllegalArgumentException("Unknown parameter #" + paramNum + " of " + bestMethod.getName() + ".");
+ }
}
results = (WOActionResults)bestMethod.invoke(this, params);
}
@@ -0,0 +1,31 @@
+package er.rest.routes.jsr311;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * <p>
+ * Like JSR-311, @CookieParam allows you to annotate an action method parameter to specify
+ * that its value should be loaded from the cookie parameters.
+ * </p>
+ *
+ * <pre>
+ * public WOActionResults testAction(@CookieParam("person") Person personParam) {
+ * ...
+ * }
+ * </pre>
+ *
+ * <p>
+ * This will automatically pass the value of the "person" cookie object (person=10) into
+ * your action method as the "personParam" parameter.
+ * </p>
+ *
+ * @author mschrag
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.PARAMETER)
+public @interface CookieParam {
+ String value();
+}
@@ -0,0 +1,31 @@
+package er.rest.routes.jsr311;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * <p>
+ * Like JSR-311, @HeaderParam allows you to annotate an action method parameter to specify
+ * that its value should be loaded from the header parameters.
+ * </p>
+ *
+ * <pre>
+ * public WOActionResults testAction(@HeaderParam("person") Person personParam) {
+ * ...
+ * }
+ * </pre>
+ *
+ * <p>
+ * This will automatically pass the value of the "person" header object (person: 10) into
+ * your action method as the "personParam" parameter.
+ * </p>
+ *
+ * @author mschrag
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.PARAMETER)
+public @interface HeaderParam {
+ String value();
+}
@@ -0,0 +1,31 @@
+package er.rest.routes.jsr311;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * <p>
+ * Like JSR-311, @QueryParam allows you to annotate an action method parameter to specify
+ * that its value should be loaded from the query parameters.
+ * </p>
+ *
+ * <pre>
+ * public WOActionResults testAction(@QueryParam("person") Person personParam) {
+ * ...
+ * }
+ * </pre>
+ *
+ * <p>
+ * This will automatically pass the value of the "person" query object (?person=10) into
+ * your action method as the "personParam" parameter.
+ * </p>
+ *
+ * @author mschrag
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.PARAMETER)
+public @interface QueryParam {
+ String value();
+}

0 comments on commit a7b1789

Please sign in to comment.