/**
*
*/
package cn.bran.play.routing;
import static org.reflections.ReflectionUtils.getAllMethods;
import static org.reflections.ReflectionUtils.withModifier;
import static org.reflections.ReflectionUtils.withReturnType;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.regex.Pattern;
import javax.ws.rs.Path;
import play.libs.F.Tuple;
import play.mvc.Result;
import cn.bran.japid.util.JapidFlags;
import cn.bran.play.GlobalSettingsWithJapid;
import com.google.common.base.Predicates;
/**
* @author bran
*
*/
public class RouterClass {
String absPath;
Pattern absPathPatternForValues;
// List<String> routeTable = new ArrayList<String>();
Class<?> clz;
private String path;
List<RouterMethod> routerMethods = new ArrayList<RouterMethod>();
/**
* @param cl
*/
public RouterClass(Class<?> cl, String appPath) {
clz = cl;
path = cl.getAnnotation(Path.class).value();
if (path.length() == 0) {
// auto-pathing. using the class full name minus the "controller." part as the path
String cname = cl.getName();
if (cname.startsWith(JaxrsRouter.routerPackage + "."))
cname = cname.substring((JaxrsRouter.routerPackage + ".").length());
path = cname;
}
absPath = appPath + JaxrsRouter.prefixSlash(path);
String r = absPath.replaceAll(JaxrsRouter.urlParamCapture, "(.*)");
absPathPatternForValues = Pattern.compile(r);
// @SuppressWarnings("unchecked")
// Predicate<AnnotatedElement> and = Predicates.or(withAnnotation(GET.class),
// withAnnotation(POST.class), withAnnotation(PUT.class),
// withAnnotation(DELETE.class), withAnnotation(HEAD.class),
// withAnnotation(OPTIONS.class));
// Set<Method> allMethods = getAllMethods(cl, and);
// let's allow any methods
Set<Method> allMethods = getAllMethods(cl, Predicates.and(withModifier(Modifier.STATIC), withReturnType(Result.class)));
for (Method m : allMethods) {
if (m.getDeclaringClass() == cl)
routerMethods.add(new RouterMethod(m, absPath));
}
}
public Tuple<Method,Object[]> findMethodAndGenerateArgs(play.mvc.Http.RequestHeader r) {
String uri = r.path();
String contentType = "";
String[] ct = r.headers().get("Content-Type");
if (ct != null && ct.length > 0)
contentType = ct[0];
try {
for (RouterMethod m : routerMethods) {
if (m.containsConsumeType(contentType)
&& m.supportHttpMethod(r.method())
&& m.matchURI(uri)) {
return new Tuple<Method, Object[]>(m.meth, m.extractArguments(r));
}
}
} catch (Exception e) {
if (GlobalSettingsWithJapid._app.isDev())
JapidFlags.warn(e.toString());
else
JapidFlags.debug(e.toString());
}
return null;
}
@Override
public String toString() {
String ret = "";
for (RouterMethod m : routerMethods) {
ret += m.toString() + "\n";
}
return ret;
}
public List<RouteEntry> getRouteTable(){
List<RouteEntry> entries = new ArrayList<RouteEntry>();
for (RouterMethod m : routerMethods) {
entries.add(m.getRouteEntry());
}
return entries;
}
}