package com.google.sitebricks.routing; import java.io.IOException; import java.lang.annotation.Annotation; import java.util.Collection; import java.util.List; import java.util.Map; import java.util.Set; import com.google.inject.AbstractModule; import com.google.inject.ImplementedBy; import com.google.inject.Module; import com.google.inject.Stage; import com.google.sitebricks.ActionDescriptor; import com.google.sitebricks.Renderable; import com.google.sitebricks.Show; import com.google.sitebricks.headless.Request; /** * @author Dhanji R. Prasanna (dhanji@gmail.com) */ @ImplementedBy(DefaultPageBook.class) public interface PageBook { /** * Register a page class at the given contextual URI. * * @return A {@link Page} representing the given class * without a compiled template applied. */ Page at(String uri, Class<?> myPageClass); /** * * @param uri A contextual URI where a page (maybe) registered. * @return A {@link Page} object thatis capable of rend */ Page get(String uri); Page forName(String name); /** * Registers a page class as an embeddable. * @param as The annotation name to register this widget as. * Example: {@code "Hello"} will make this page class * available for embedding as <pre>{@literal @}Hello</pre>. */ Page embedAs(Class<?> pageClass, String as); /** * Indicates that the template for this class is to be * inserted into a superclass template using @Decorated * * @param pageClass */ Page decorate(Class<?> pageClass); /** * Same as {@linkplain #get} except guaranteed not to trigger a * cascading compile of page bricks. */ Page nonCompilingGet(String uri); /** * Similar to {@linkplain #get} except that instead of returning * a page for a URI, it returns the page matching the class of the * provided instance, and uses the instance itself to deliver the * page. * * @param instance An instance of some page registered by an {@literal @}{@code At} * annotation or similar method in this sitebricks app. */ Page forInstance(Object instance); /** * Very similar to {@linkplain #forInstance(Object)}, except that it * takes a class literal instead and does NOT do super crawling. */ Page forClass(Class<?> pageClass); /** * Same as {@linkplain #at} but registers a headless web service instead. */ Page serviceAt(String uri, Class<?> pageClass); Collection<List<Page>> getPageMap(); void at(String uri, List<ActionDescriptor> actionDescriptor, Map<Class<? extends Annotation>, String> methodSet); public static interface Page extends Comparable<Page> { Renderable widget(); Object instantiate(); Object doMethod(String httpMethod, Object page, String pathInfo, Request request) throws IOException; Class<?> pageClass(); void apply(Renderable widget); String getUri(); boolean isHeadless(); boolean isDecorated(); Set<String> getMethod(); Show getShow(); } public static final class Routing extends AbstractModule { private Routing() { } @Override protected final void configure() { if (Stage.DEVELOPMENT.equals(binder().currentStage())) { bind(PageBook.class) .annotatedWith(Production.class) .to(DefaultPageBook.class); bind(RoutingDispatcher.class) .annotatedWith(Production.class) .to(WidgetRoutingDispatcher.class); } } public static Module module() { return new Routing(); } //Ensures only one instance of the Routine module is installed. @Override public boolean equals(Object obj) { return obj instanceof Routing; } @Override public int hashCode() { return Routing.class.hashCode(); } } }