Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge pull request #478 from nykolaslima/linkTo_overloaded_methods

linkTo support to overloaded methods
  • Loading branch information...
commit e13f72a89173e7b0d03fb30fc833bbfbd1bfecb2 2 parents cc185fd + 3297ac6
@lucascs lucascs authored
View
86 vraptor-core/src/main/java/br/com/caelum/vraptor/view/LinkToHandler.java
@@ -16,11 +16,15 @@
package br.com.caelum.vraptor.view;
import java.lang.reflect.Method;
+import java.util.ArrayList;
import java.util.Collections;
+import java.util.List;
import java.util.Map;
import javax.servlet.ServletContext;
+import net.vidageek.mirror.dsl.Mirror;
+
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -74,22 +78,10 @@ public LinkMethod(Class<?> controller) {
@Override
public Linker get(Object key) {
- Method method = findMethodWithName(controller, (String) key);
-
- return new Linker(controller, method);
- }
- private Method findMethodWithName(Class<?> type, String name) {
- for (Method method : type.getDeclaredMethods()) {
- if (!method.isBridge() && method.getName().equals(name)) {
- return method;
- }
- }
- if (type.getSuperclass().equals(Object.class)) {
- throw new IllegalArgumentException("There are no methods on " + controller + " named " + name);
- }
- return findMethodWithName(type.getSuperclass(), name);
+ return new Linker(controller, key.toString());
}
+
@Override
public String toString() {
throw new IllegalArgumentException("uncomplete linkTo[" + controller.getSimpleName() + "]. You must specify the method.");
@@ -98,27 +90,25 @@ public String toString() {
class Linker extends ForwardingMap<Object, Linker> {
- private final Object[] args;
- private final Method method;
+ private final List<Object> args;
+ private final String methodName;
private final Class<?> controller;
- private final int filled;
- public Linker(Class<?> controller, Method method) {
- this(controller, method, new Object[method.getParameterTypes().length], 0);
+ public Linker(Class<?> controller, String methodName) {
+ this(controller, methodName, new ArrayList<Object>());
}
- public Linker(Class<?> controller, Method method, Object[] args, int filled) {
+ public Linker(Class<?> controller, String methodName, List<Object> args) {
this.controller = controller;
- this.method = method;
+ this.methodName = methodName;
this.args = args;
- this.filled = filled;
}
@Override
public Linker get(Object key) {
- Object[] newArgs = args.clone();
- newArgs[filled] = key;
- return new Linker(controller, method, newArgs, filled + 1);
+ List<Object> newArgs = new ArrayList<Object>(args);
+ newArgs.add(key);
+ return new Linker(controller, methodName, newArgs);
}
@Override
@@ -128,7 +118,51 @@ public Linker get(Object key) {
@Override
public String toString() {
- return context.getContextPath() + router.urlFor(controller, method, args);
+ Method method = null;
+
+ if(getMethodsAmountWithSameName() > 1 && args.size() > 0) {
+ method = new Mirror().on(controller).reflect().method(methodName).withArgs(getClasses(args));
+ } else {
+ method = findMethodWithName(controller, methodName);
+ }
+
+ if(method == null)
+ throw new IllegalArgumentException("There are no methods on " + controller + " named " + methodName);
+
+ return context.getContextPath() + router.urlFor(controller, method, args.toArray());
}
+
+ private Method findMethodWithName(Class<?> type, String name) {
+ for (Method method : type.getDeclaredMethods()) {
+ if (!method.isBridge() && method.getName().equals(name)) {
+ return method;
+ }
+ }
+
+ if (type.getSuperclass().equals(Object.class)) {
+ return null;
+ }
+
+ return findMethodWithName(type.getSuperclass(), name);
+ }
+
+ private int getMethodsAmountWithSameName() {
+ int amount = 0;
+ for (Method method : controller.getDeclaredMethods()) {
+ if (!method.isBridge() && method.getName().equals(methodName)) {
+ amount++;
+ }
+ }
+
+ return amount;
+ }
+
+ private Class<?>[] getClasses(List<Object> params) {
+ Class<?>[] classes = new Class<?>[params.size()];
+ for(int i = 0; i < params.size(); i ++) {
+ classes[i] = params.get(i).getClass();
+ }
+ return classes;
+ }
}
}
View
16 vraptor-core/src/test/java/br/com/caelum/vraptor/view/LinkToHandlerTest.java
@@ -38,7 +38,7 @@ public void shouldThrowExceptionWhenInvokingInexistantMethod() {
}
@Test
public void shouldReturnWantedUrlWithoutArgs() {
- when(router.urlFor(TestController.class, TestController.class.getDeclaredMethods()[0], new Object[2])).thenReturn("/expectedURL");
+ when(router.urlFor(TestController.class, TestController.class.getDeclaredMethods()[0], new Object[0])).thenReturn("/expectedURL");
//${linkTo[TestController].method}
String uri = handler.get(TestController.class).get("method").toString();
@@ -63,10 +63,22 @@ public void shouldReturnWantedUrlForOverrideMethodWithParamArgs() throws NoSuchM
String uri = handler.get(SubGenericController.class).get("method").get(a).toString();
assertThat(uri, is("/path/expectedURL"));
}
-
+
+ @Test
+ public void shouldReturnWantedUrlForMethodsWithSameName() {
+ String a = "test";
+ when(router.urlFor(TestController.class, TestController.class.getDeclaredMethods()[1], a)).thenReturn("/expectedUrl");
+ //${linkTo[TestController].method['test']}
+ String uri = handler.get(TestController.class).get("method").get(a).toString();
+ assertThat(uri, is("/path/expectedUrl"));
+ }
+
static class TestController {
void method(String a, int b) {
}
+ void method(String a) {
+
+ }
}
}
Please sign in to comment.
Something went wrong with that request. Please try again.