Package cn.bran.play.routing

Source Code of cn.bran.play.routing.JaxrsRouter

/**
*
*/
package cn.bran.play.routing;

import java.lang.reflect.InvocationTargetException;
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.ApplicationPath;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;

import org.reflections.Reflections;
import org.reflections.scanners.TypeAnnotationsScanner;
import org.reflections.util.ClasspathHelper;
import org.reflections.util.ConfigurationBuilder;
import org.reflections.util.FilterBuilder;

import cn.bran.japid.util.JapidFlags;
import play.Application;
import play.GlobalSettings;
import play.api.mvc.Handler;
import play.libs.F.Tuple;
import play.mvc.Result;
import play.mvc.SimpleResult;

/**
* @author bran
*
*/
public class JaxrsRouter {
  static String routerPackage = "controllers";
  static final String ASSET_SERVING = "jaxrc.assets.serving";
  static String[] assetServing = new String[] { "/assets", "/public" }; // format:
                                      // "user space asset root, folder on file system"
//
//  static Reflections ref = new Reflections(new ConfigurationBuilder()
//      .filterInputsBy(new FilterBuilder().include(routerPackage + ".*"))
//      .setScanners(new TypeAnnotationsScanner()).setUrls(ClasspathHelper.forPackage(routerPackage)));

  static String urlParamCapture = "\\{(.*?)\\}";
  static Pattern urlParamCaptureP = Pattern.compile(urlParamCapture);
  private static ClassLoader parentClassloader;
  private static Set<Class<?>> classes;
  private static GlobalSettings global;
  private static String appPath = "";

  static String prefixSlash(String s) {
    return s.startsWith("/") ? s : "/" + s;
  }

  private static List<RouterClass> routerClasses = new ArrayList<RouterClass>();

  public static void init(Application app, play.GlobalSettings g) {
    parentClassloader = app.classloader();
    classes = RouterUtils.classes(parentClassloader);
    global = g;
    ApplicationPath appPathAnno = global.getClass().getAnnotation(ApplicationPath.class);
    if (appPathAnno != null)
      appPath = appPathAnno.value();

    routerClasses = parseRouterClasses(classes);

    String string = app.configuration().getString(ASSET_SERVING);
    if (string != null)
      assetServing = string.split(",");
  }

  /**
   * @author Bing Ran (bing.ran@gmail.com)
   * @param classes2
   * @return
   */
  private static List<RouterClass> parseRouterClasses(Set<Class<?>> classes2) {
    List<RouterClass> routers = new ArrayList<RouterClass>();

    for (Class<?> cl : classes2) {
      JapidFlags.info("found class with JAX-RS Path annotation: " + cl.getName());
      routers.add(new RouterClass(cl, appPath));
    }
    return routers;
  }

  /**
   * provides a handler for given request
   *
   * @param global
   *            the global of the current play application
   * @param r
   *            request header
   * @return action handler
   *
   */
  public static Handler handlerFor(final play.mvc.Http.RequestHeader r) {
    if (assetServing.length == 2 && r.path().startsWith(assetServing[0])) {
      // serve static asset
//      return controllers.Assets.at(assetServing[1], r.path().replaceFirst(assetServing[0], ""));
      return null;
    } else {
      final RouterClass targetRouterClass = RouterUtils.findLongestMatch(routerClasses, r);
      if (targetRouterClass == null)
        return null;

      final Tuple<Method, Object[]> methodWithArgs = targetRouterClass.findMethodAndGenerateArgs(r);

      if (methodWithArgs != null) {
        ResultBuilder resultBuilder = new ResultBuilder() {
          @Override
          public SimpleResult create() {
            try {
              Method m = methodWithArgs._1;
              Class<?> cl = targetRouterClass.clz;
              Object obj = global.getControllerInstance(cl);
              if (obj == null && (m.getModifiers() & Modifier.STATIC) != Modifier.STATIC) {
                throw new RuntimeException("the action method is not static while the target object is null: " + targetRouterClass.clz + "#" + m.getName());
              }
              Object[] args = methodWithArgs._2;
              SimpleResult result = (SimpleResult)m.invoke(obj, args);
              Produces produces = methodWithArgs._1.getAnnotation(Produces.class);
              return produces != null ? new WrapProducer(produces.value()[0], result) : result;
            } catch (InvocationTargetException cause) {
              System.err.println("Exception occured while trying to invoke: " + targetRouterClass.clz.getName()
                  + "#" + methodWithArgs._1.getName() + " with " + methodWithArgs._2 + " for uri:" + r.path());
              throw new RuntimeException(cause.getCause());
            } catch (Exception e) {
              e.printStackTrace();
              throw new RuntimeException(e.getCause());
            }
          }
        };

        JavaActionBridge handler = new JavaActionBridge(targetRouterClass.clz, methodWithArgs._1, resultBuilder);
        return handler;
      }
    }
    JapidFlags.debug("Japid router could not route this request");
    return null;
  }

  /**
   * @author Bing Ran (bing.ran@gmail.com)
   * @param classloader
   */
  public static void setClassLoader(ClassLoader classloader) {
    parentClassloader = classloader;
  }

  public static String getRouteTableString() {
    String s = "";
    for (RouterClass c : routerClasses) {
      s += c.toString();
    }
    return s;
  }

  public static List<RouteEntry> getRouteTable() {
    List<RouteEntry> ret = new ArrayList<RouteEntry>();
    for (RouterClass c : routerClasses) {
      ret.addAll(c.getRouteTable());
    }
    return ret;
  }
 
  static public Set<Class<?>> getControllersWithPath() {
    Reflections reflections = new Reflections(routerPackage);
    Set<Class<?>> annotated = reflections.getTypesAnnotatedWith(Path.class);
    return annotated;
  }
}
TOP

Related Classes of cn.bran.play.routing.JaxrsRouter

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.