Package com.github.dynamicextensionsalfresco.webscripts

Source Code of com.github.dynamicextensionsalfresco.webscripts.AnnotationWebScript

package com.github.dynamicextensionsalfresco.webscripts;

import com.github.dynamicextensionsalfresco.webscripts.annotations.Attribute;
import com.github.dynamicextensionsalfresco.webscripts.arguments.HandlerMethodArgumentsResolver;
import com.github.dynamicextensionsalfresco.webscripts.resolutions.DefaultResolutionParameters;
import com.github.dynamicextensionsalfresco.webscripts.resolutions.Resolution;
import com.github.dynamicextensionsalfresco.webscripts.resolutions.TemplateResolution;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.extensions.webscripts.*;
import org.springframework.util.Assert;
import org.springframework.util.ReflectionUtils;
import org.springframework.util.StringUtils;

import java.io.IOException;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;
import java.util.ResourceBundle;

public class AnnotationWebScript implements WebScript {
  /* Dependencies */

  private HandlerMethodArgumentsResolver argumentsResolver;

  /* Configuration */

  private final Description description;

  private final Object handler;

  private final HandlerMethods handlerMethods;

  private final String id;

  /* Main operations */

  public AnnotationWebScript(final Description description, final Object handler,
      final HandlerMethods handlerMethods, final HandlerMethodArgumentsResolver argumentsResolver) {
    Assert.notNull(description, "Description cannot be null.");
    Assert.hasText(description.getId(), "No ID provided in Description.");
    Assert.notNull(handler, "Handler cannot be null.");
    Assert.notNull(handlerMethods, "Methods cannot be null.");

    this.description = description;
    this.handler = handler;
    this.handlerMethods = handlerMethods;
    this.argumentsResolver = argumentsResolver;
    this.id = description.getId();
  }

  public Object getHandler() {
    return handler;
  }

  public HandlerMethods getHandlerMethods() {
    return handlerMethods;
  }

  @Override
  public final void execute(final WebScriptRequest request, final WebScriptResponse response) throws IOException {
    final AnnotationWebScriptRequest annotationRequest = new AnnotationWebScriptRequest(request);
    final AnnotationWebscriptResponse wrappedResponse = new AnnotationWebscriptResponse(response);
    try {
      invokeAttributeHandlerMethods(annotationRequest, wrappedResponse);
      invokeBeforeHandlerMethods(annotationRequest, wrappedResponse);
      final Object returnValue = invokeUriHandlerMethod(annotationRequest, wrappedResponse);
      handleUriMethodReturnValue(handlerMethods, annotationRequest, wrappedResponse, returnValue);
    } catch (final Throwable e) {
      invokeExceptionHandlerMethods(e, annotationRequest, wrappedResponse);
    }
  }

  /*
   * This method appears to be new in the Web Scripts 1.0.0 API. This implementation does nothing, because we want to
   * retain backwards-compatibility.
   */
  @Override
  public void init(final Container container, final Description description) {
  }

  @Override
  public Description getDescription() {
    return description;
  }

  @Override
  public ResourceBundle getResources() {
    /* Not yet supported. */
    return null;
  }

  @Override
  public void setURLModelFactory(final URLModelFactory arg0) {
    /* Not yet implemented. */
  }

  /* Handler operations */

  protected boolean invokeBeforeHandlerMethods(final AnnotationWebScriptRequest request,
      final WebScriptResponse response) {
    for (final Method method : handlerMethods.getBeforeMethods()) {
      method.setAccessible(true);
      final Object[] arguments = getArgumentsResolver().resolveHandlerMethodArguments(method, handler, request,
          response);
      final Object returnValue = ReflectionUtils.invokeMethod(method, handler, arguments);
      if (Boolean.FALSE.equals(returnValue)) {
        return false;
      }
    }
    return true;

  }

  protected void invokeAttributeHandlerMethods(final AnnotationWebScriptRequest request,
      final WebScriptResponse response) {
    for (final Method method : handlerMethods.getAttributeMethods()) {
      method.setAccessible(true);
      final Object[] arguments = getArgumentsResolver().resolveHandlerMethodArguments(method, handler, request,
          response);
      final Object attribute = ReflectionUtils.invokeMethod(method, handler, arguments);
      if (attribute == null) {
        continue;
      }
      final Attribute annotation = AnnotationUtils.findAnnotation(method, Attribute.class);
      final Map<String, Object> model = request.getModel();
      if (StringUtils.hasText(annotation.value())) {
        model.put(annotation.value(), attribute);
      } else {
        String name = method.getName();
        if (name.startsWith("get") && name.length() > 3) {
          name = name.substring(3, 4).toLowerCase() + name.substring(4);
        }
        model.put(name, attribute);
      }
    }
  }

  protected Object invokeUriHandlerMethod(final AnnotationWebScriptRequest request,
      final AnnotationWebscriptResponse response) {
    final Method uriMethod = handlerMethods.getUriMethod();
    final Object[] arguments = argumentsResolver.resolveHandlerMethodArguments(uriMethod, handler, request,
        response);
    uriMethod.setAccessible(true);
    return ReflectionUtils.invokeMethod(uriMethod, handler, arguments);
  }

  @SuppressWarnings("unchecked")
  protected void handleUriMethodReturnValue(HandlerMethods handlerMethods, final AnnotationWebScriptRequest request,
                                              final AnnotationWebscriptResponse response, final Object returnValue) throws Exception {
        Resolution resolution = null;
        if (returnValue instanceof Map) {
            resolution = new TemplateResolution((Map<String, Object>) returnValue);
        } else if (returnValue instanceof String) {
            resolution = new TemplateResolution((String)returnValue);
        } else if (returnValue instanceof Resolution) {
            resolution = (Resolution) returnValue;
        }
        if (this.handlerMethods.useResponseTemplate()) {
            final String responseTemplateName = handlerMethods.getResponseTemplateName();
            if (responseTemplateName != null) {
                if (resolution instanceof TemplateResolution) {
                    if (((TemplateResolution) resolution).getTemplate() == null) {
                        ((TemplateResolution) resolution).setTemplate(responseTemplateName);
                    }
                } else if (resolution == null) {
                    resolution = new TemplateResolution(responseTemplateName);
                }
            }
        }
        if (resolution != null) {
            if (resolution instanceof TemplateResolution) {
                final TemplateResolution templateResolution = (TemplateResolution)resolution;
                final Map<String, Object> model = request.getModel();

                if (templateResolution.getModel() != null && templateResolution.getModel() != model) {
                    model.putAll(templateResolution.getModel());
                }
                templateResolution.setModel(model);
            }

            resolution.resolve(request, response,
                new DefaultResolutionParameters(handlerMethods.getUriMethod(), description, handler)
            );
        }
    }

  protected void invokeExceptionHandlerMethods(final Throwable exception, final AnnotationWebScriptRequest request,
      final WebScriptResponse response) throws IOException {
    final List<Method> exceptionHandlerMethods = handlerMethods.findExceptionHandlers(exception);
    if (exceptionHandlerMethods.isEmpty()) {
      translateException(exception);
    }
    try {
      request.setThrownException(exception);
      for (final Method exceptionHandler : exceptionHandlerMethods) {
        final Object[] arguments = getArgumentsResolver().resolveHandlerMethodArguments(exceptionHandler,
            handler, request, response);
        exceptionHandler.setAccessible(true);
        ReflectionUtils.invokeMethod(exceptionHandler, handler, arguments);
      }
    } catch (final Throwable e) {
      translateException(e);
    } finally {
      request.setThrownException(null);
    }

  }

  /* Utility operations */

  protected void translateException(final Throwable e) throws IOException {
    if (e instanceof IOException) {
      throw (IOException) e;
    } else if (e instanceof RuntimeException) {
      throw (RuntimeException) e;
    } else {
      throw new RuntimeException(e);
    }
  }

  /* Dependencies */

  public void setArgumentsResolver(final HandlerMethodArgumentsResolver handlerMethodArgumentsResolver) {
    Assert.notNull(handlerMethodArgumentsResolver);
    this.argumentsResolver = handlerMethodArgumentsResolver;
  }

  protected HandlerMethodArgumentsResolver getArgumentsResolver() {
    return argumentsResolver;
  }

  /* Equality operations */

  @Override
  public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + ((id == null) ? 0 : id.hashCode());
    return result;
  }

  @Override
  public boolean equals(final Object obj) {
    if (this == obj) {
      return true;
    }
    if (obj == null) {
      return false;
    }
    if (getClass() != obj.getClass()) {
      return false;
    }
    final AnnotationWebScript other = (AnnotationWebScript) obj;
    if (id == null) {
      if (other.id != null) {
        return false;
      }
    } else if (!id.equals(other.id)) {
      return false;
    }
    return true;
  }

}
TOP

Related Classes of com.github.dynamicextensionsalfresco.webscripts.AnnotationWebScript

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.