Package com.google.sitebricks.routing

Source Code of com.google.sitebricks.routing.WidgetRoutingDispatcher

package com.google.sitebricks.routing;

import java.io.IOException;
import java.util.List;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import javax.validation.ValidationException;

import net.jcip.annotations.Immutable;

import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton;
import com.google.sitebricks.Respond;
import com.google.sitebricks.StringBuilderRespond;
import com.google.sitebricks.binding.FlashCache;
import com.google.sitebricks.binding.RequestBinder;
import com.google.sitebricks.client.transport.Json;
import com.google.sitebricks.conversion.ValidationConverter;
import com.google.sitebricks.headless.HeadlessRenderer;
import com.google.sitebricks.headless.Reply;
import com.google.sitebricks.headless.Request;
import com.google.sitebricks.rendering.resource.ResourcesService;
import com.google.sitebricks.routing.PageBook.Page;

/**
* @author Dhanji R. Prasanna (dhanji@gmail.com)
*/
@Immutable
@Singleton
class WidgetRoutingDispatcher implements RoutingDispatcher {
  private final PageBook book;
  private final RequestBinder binder;
  private final ResourcesService resourcesService;
  private final Provider<FlashCache> flashCacheProvider;
  private final HeadlessRenderer headlessRenderer;

  @Inject
  Provider<HttpServletRequest> httpServletRequestProvider;
 
  @Inject
  private ValidationConverter validationConvertor;

  @Inject
  public WidgetRoutingDispatcher(PageBook book, RequestBinder<String> binder,
                                 ResourcesService resourcesService,
                                 Provider<FlashCache> flashCacheProvider,
                                 HeadlessRenderer headlessRenderer) {
    this.headlessRenderer = headlessRenderer;
    this.book = book;
    this.binder = binder;
    this.resourcesService = resourcesService;
    this.flashCacheProvider = flashCacheProvider;
  }

  public Object dispatch(Request request, Events event) throws IOException {
    String uri = request.path();

    //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.
    // TODO(dhanji): Change flashcache to use temporary cookies instead.
    PageBook.Page page = flashCacheProvider.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;

    final Object instance = page.instantiate();
    if (page.isHeadless()) {
      return bindAndReply(request, page, instance);
    } else {
       //fire events and render responder
      return bindAndRespond(request, page, instance);
    }
  }

  private Object bindAndReply(Request request, Page page, Object instance) throws IOException {
    // bind request (sets request params, etc).
    binder.bind(request, instance);
   
    Object response = null;
    try {
        // call the appropriate handler.
        response = fireEvent(request, page, instance);
    }
    catch (ValidationException ve) {
        ConstraintViolationException cve = (ConstraintViolationException) ve.getCause();
        Set<? extends ConstraintViolation<?>> scv = (Set<? extends ConstraintViolation<?>>) cve.getConstraintViolations();
        List<String> errors = validationConvertor.to(scv);
        response =  Reply.with(errors).as(Json.class).badRequest();
    }
    return response;
  }

  private Object bindAndRespond(Request request, PageBook.Page page, Object instance)
      throws IOException {
    //bind request
    binder.bind(request, instance);

    // fire get/post events
    Object redirect = null;
    List<String> errors = null;
    try {
        redirect = fireEvent(request, page, instance);
    }
    catch (ValidationException ve) {
        ve.getCause().printStackTrace();
        ConstraintViolationException cve = (ConstraintViolationException) ve.getCause();
        Set<? extends ConstraintViolation<?>> scv = (Set<? extends ConstraintViolation<?>>) cve.getConstraintViolations();
        errors = validationConvertor.to(scv);
    }
       
    //render to respond
    Respond respond = new StringBuilderRespond(instance);
    respond.setErrors(errors);
    if (null != redirect) {

      if (redirect instanceof String)
        respond.redirect((String) redirect);
      else if (redirect instanceof Class) {
        PageBook.Page targetPage = book.forClass((Class<?>) redirect);

        // should never be null coz it is validated on compile.
        respond.redirect(contextualize(request, targetPage.getUri()));
      } else if (redirect instanceof Reply<?>) {
        // To allow non-headless pages to use Reply<?> for more advanced HTTP responses
        return 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.
        flashCacheProvider.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);
    }
   
    return respond;
  }

  // We're sure the request parameter map is a Map<String, String[]>
  @SuppressWarnings("unchecked")
  private Object fireEvent(Request request, PageBook.Page page, Object instance)
      throws IOException {
    final String method = request.method();
    final String pathInfo = request.path();

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

  private static String contextualize(Request request, String targetUri) {
    return request.context() + targetUri;
  }
 
}
TOP

Related Classes of com.google.sitebricks.routing.WidgetRoutingDispatcher

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.