All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.google.sitebricks.routing.WidgetRoutingDispatcher Maven / Gradle / Ivy

package com.google.sitebricks.routing;

import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton;
import com.google.sitebricks.Respond;
import com.google.sitebricks.binding.FlashCache;
import com.google.sitebricks.binding.RequestBinder;
import com.google.sitebricks.rendering.resource.ResourcesService;
import net.jcip.annotations.Immutable;

import javax.servlet.http.HttpServletRequest;

/**
 * @author Dhanji R. Prasanna ([email protected])
 */
@Immutable
@Singleton
class WidgetRoutingDispatcher implements RoutingDispatcher {
  private final PageBook book;
  private final RequestBinder binder;
  private final Provider respondProvider;
  private final ResourcesService resourcesService;
  private final Provider flashCache;

  @Inject
  public WidgetRoutingDispatcher(PageBook book, RequestBinder binder, Provider respondProvider,
                                 ResourcesService resourcesService, Provider flashCache) {
    this.book = book;
    this.binder = binder;
    this.respondProvider = respondProvider;
    this.resourcesService = resourcesService;
    this.flashCache = flashCache;
  }

  public Respond dispatch(HttpServletRequest request) {
    String uri = getPathInfo(request);

    //first try dispatching as a static resource service
    Respond respond = resourcesService.serve(uri);

    if (null != respond)
      return respond;

    // Otherwise try to dispatch as a widget/page
    // Check if there is a page chain link sitting here
    // for this page.
    // NOTE(dhanji): we must use remove, to atomically
    // remove the page and process it in one go. It is
    // also worth coordinating this with conversation request
    // queueing.
    PageBook.Page page = flashCache.get().remove(uri);

    // If there is no link, obtain page via Guice as normal.
    if (null == page)
      page = book.get(uri);

    //could not dispatch as there was no match
    if (null == page)
      return null;

    respond = respondProvider.get();
    final Object instance = page.instantiate();

    //fire events and render reponders
    bindAndRespond(request, page, respond, instance);

    return respond;
  }

  private String getPathInfo(HttpServletRequest request) {
    return request.getRequestURI().substring(request.getContextPath().length());
  }

  private void bindAndRespond(HttpServletRequest request, PageBook.Page page, Respond respond,
                              Object instance) {
    //bind request
    binder.bind(request, instance);

    //fire get/post events
    final Object redirect = fireEvent(request, page, instance);

    //render to respond
    if (null != redirect) {

      if (redirect instanceof String)
        respond.redirect((String) redirect);
      else {
        // Handle page-chaining driven redirection.
        PageBook.Page targetPage = book.forInstance(redirect);

        // should never be null coz it will be validated at compile time.
        flashCache.get().put(targetPage.getUri(), targetPage);

        // Send to the canonical address of the page. This is also
        // verified at compile, not be a variablized matcher.
        respond.redirect(contextualize(request, targetPage.getUri()));
      }
    } else
      page.widget().render(instance, respond);
  }

  // We're sure the request parameter map is a Map
  @SuppressWarnings("unchecked")
  private Object fireEvent(HttpServletRequest request, PageBook.Page page, Object instance) {
    final String method = request.getMethod();
    final String pathInfo = getPathInfo(request);

    return page.doMethod(method.toLowerCase(), instance, pathInfo, request.getParameterMap());
  }

  private static String contextualize(HttpServletRequest request, String targetUri) {
    return request.getContextPath() + targetUri;
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy