private Router createRootTreeAcceptor( RouteToPathBuilder<PathPattern> lastRoutedBuilder, boolean subResourceMode) { final Router routingRoot; if (lastRoutedBuilder != null) { routingRoot = lastRoutedBuilder.build(); } else { /** * Create an empty routing root that accepts any request, does not do anything and does not * return any inflector. This will cause 404 being returned for every request. */ routingRoot = Routers.acceptingTree( new Function<ContainerRequest, ContainerRequest>() { @Override public ContainerRequest apply(ContainerRequest input) { return input; } }) .build(); } if (subResourceMode) { return routingRoot; } else { return rootBuilder.root(routingRoot); } }
/** * Build a runtime model. * * @param subResourceMode if {@code true}, all resources will be processed as sub-resources. * @return runtime request routing root. */ public Router buildModel(boolean subResourceMode) { final PushMatchedUriRouter uriPushingRouter = locator.createAndInitialize(PushMatchedUriRouter.class); RouteToPathBuilder<PathPattern> lastRoutedBuilder = null; // route resource method acceptors if (!rootAcceptors.isEmpty()) { for (Map.Entry<PathPattern, List<MethodAcceptorPair>> entry : rootAcceptors.entrySet()) { final PathPattern closedResourcePathPattern = entry.getKey(); List<MethodAcceptorPair> methodAcceptorPairs = entry.getValue(); lastRoutedBuilder = routeMethodAcceptor( lastRoutedBuilder, closedResourcePathPattern, uriPushingRouter, methodSelectingAcceptorBuilder.build(workers, methodAcceptorPairs), subResourceMode); } rootAcceptors.clear(); } // route sub-resource method and locator acceptors if (!subResourceAcceptors.isEmpty()) { for (Map.Entry<PathPattern, TreeMap<PathPattern, List<MethodAcceptorPair>>> singleResourcePathEntry : subResourceAcceptors.entrySet()) { RouteToPathBuilder<PathPattern> srRoutedBuilder = null; for (Map.Entry<PathPattern, List<MethodAcceptorPair>> singlePathEntry : singleResourcePathEntry.getValue().entrySet()) { // there can be multiple sub-resource methods on the same path // but only a single sub-resource locator. List<MethodAcceptorPair> resourceMethods = Lists.newLinkedList(); MethodAcceptorPair resourceLocator = null; for (MethodAcceptorPair methodAcceptorPair : singlePathEntry.getValue()) { if (methodAcceptorPair.model.getType() == ResourceMethod.JaxrsType.RESOURCE_METHOD) { resourceMethods.add(methodAcceptorPair); } else { resourceLocator = methodAcceptorPair; } } if (!resourceMethods.isEmpty()) { final PathPattern subResourceMethodPath = PathPattern.asClosed(singlePathEntry.getKey()); srRoutedBuilder = routedBuilder(srRoutedBuilder) .route(subResourceMethodPath) .to(uriPushingRouter) .to(methodSelectingAcceptorBuilder.build(workers, resourceMethods)); } if (resourceLocator != null) { srRoutedBuilder = routedBuilder(srRoutedBuilder) .route(singlePathEntry.getKey()) .to(uriPushingRouter) .to(resourceLocator.router); } } assert srRoutedBuilder != null; lastRoutedBuilder = routeMethodAcceptor( lastRoutedBuilder, singleResourcePathEntry.getKey(), uriPushingRouter, srRoutedBuilder.build(), subResourceMode); } subResourceAcceptors.clear(); } return createRootTreeAcceptor(lastRoutedBuilder, subResourceMode); }