Package br.com.caelum.vraptor.view

Source Code of br.com.caelum.vraptor.view.DefaultLogicResult

/***
* Copyright (c) 2009 Caelum - www.caelum.com.br/opensource
* All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package br.com.caelum.vraptor.view;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Type;

import javax.inject.Inject;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import br.com.caelum.vraptor.Get;
import br.com.caelum.vraptor.core.MethodInfo;
import br.com.caelum.vraptor.http.MutableRequest;
import br.com.caelum.vraptor.http.MutableResponse;
import br.com.caelum.vraptor.http.route.Router;
import br.com.caelum.vraptor.interceptor.TypeNameExtractor;
import br.com.caelum.vraptor.ioc.Container;
import br.com.caelum.vraptor.proxy.MethodInvocation;
import br.com.caelum.vraptor.proxy.Proxifier;
import br.com.caelum.vraptor.proxy.ProxyInvocationException;
import br.com.caelum.vraptor.proxy.SuperMethod;
import br.com.caelum.vraptor.resource.DefaultResourceMethod;
import br.com.caelum.vraptor.resource.HttpMethod;
import br.com.caelum.vraptor.resource.ResourceMethod;
import br.com.caelum.vraptor.util.Stringnifier;

/**
* The default implementation of LogicResult.<br>
* Uses cglib to provide proxies for client side redirect (url creation).
*
* @author Guilherme Silveira
*/
public class DefaultLogicResult implements LogicResult {

  private static final Logger logger = LoggerFactory.getLogger(DefaultLogicResult.class);

  private final Proxifier proxifier;
  private final Router router;
  private final MutableRequest request;
  private final MutableResponse response;
  private final Container container;
  private final PathResolver resolver;
  private final TypeNameExtractor extractor;

  private final FlashScope flash;
  private final MethodInfo methodInfo;

  @Inject
  public DefaultLogicResult(Proxifier proxifier, Router router, MutableRequest request, MutableResponse response,
      Container container, PathResolver resolver, TypeNameExtractor extractor, FlashScope flash, MethodInfo methodInfo) {
    this.proxifier = proxifier;
    this.response = response;
    this.request = request;
    this.router = router;
    this.container = container;
    this.resolver = resolver;
    this.extractor = extractor;
    this.flash = flash;
    this.methodInfo = methodInfo;
  }

  /**
   * This implementation don't actually use request dispatcher for the
   * forwarding. It runs forwarding logic, and renders its <b>default</b>
   * view.
   */
  public <T> T forwardTo(final Class<T> type) {
    return proxifier.proxify(type, new MethodInvocation<T>() {
      public Object intercept(T proxy, Method method, Object[] args, SuperMethod superMethod) {
        try {
          logger.debug("Executing {}", Stringnifier.simpleNameFor(method));
          ResourceMethod old = methodInfo.getResourceMethod();
          methodInfo.setResourceMethod(DefaultResourceMethod.instanceFor(type, method));
          Object result = method.invoke(container.instanceFor(type), args);
          methodInfo.setResourceMethod(old);

          Type returnType = method.getGenericReturnType();
          if (!(returnType == void.class)) {
            request.setAttribute(extractor.nameFor(returnType), result);
          }
          if (!response.isCommitted()) {
            String path = resolver.pathFor(DefaultResourceMethod.instanceFor(type, method));
            logger.debug("Forwarding to {}", path);
            request.getRequestDispatcher(path).forward(request, response);
          }
          return null;
        } catch (InvocationTargetException e) {
          if (e.getCause() instanceof RuntimeException) {
            throw (RuntimeException) e.getCause();
          }
          throw new ProxyInvocationException(e);
        } catch (Exception e) {
          throw new ProxyInvocationException(e);
        }
      }
    });
  }

  private <T> void includeParametersInFlash(final Class<T> type, Method method, Object[] args) {
    if (args != null && args.length != 0) {
      flash.includeParameters(DefaultResourceMethod.instanceFor(type, method), args);
    }
  }

  public <T> T redirectTo(final Class<T> type) {
    logger.debug("redirecting to class {}", type.getSimpleName());

    return proxifier.proxify(type, new MethodInvocation<T>() {
      public Object intercept(T proxy, Method method, Object[] args, SuperMethod superMethod) {
        if (!acceptsHttpGet(method)) {
          throw new IllegalArgumentException(
              "Your logic method must accept HTTP GET method if you want to redirect to it");
        }
        try {
          String path = request.getContextPath();
          String url = router.urlFor(type, method, args);
          includeParametersInFlash(type, method, args);

          path = path + url;

          logger.debug("redirecting to {}", path);
          response.sendRedirect(path);
          return null;
        } catch (IOException e) {
          throw new ProxyInvocationException(e);
        }
      }

    });
  }

  private boolean acceptsHttpGet(Method method) {
    if (method.isAnnotationPresent(Get.class)) {
      return true;
    }
    for (HttpMethod httpMethod : HttpMethod.values()) {
      if (method.isAnnotationPresent(httpMethod.getAnnotation())) {
        return false;
      }
    }
    return true;
  }

}
TOP

Related Classes of br.com.caelum.vraptor.view.DefaultLogicResult

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.