/**
   * Evalutes the given WebApplicationContext for all HandlerInterceptor and WebRequestInterceptor
   * instances
   *
   * @param webContext The WebApplicationContext
   * @return An array of HandlerInterceptor instances
   */
  protected HandlerInterceptor[] establishInterceptors(WebApplicationContext webContext) {
    HandlerInterceptor[] interceptors;
    String[] interceptorNames = webContext.getBeanNamesForType(HandlerInterceptor.class);
    String[] webRequestInterceptors = webContext.getBeanNamesForType(WebRequestInterceptor.class);
    interceptors = new HandlerInterceptor[interceptorNames.length + webRequestInterceptors.length];

    // Merge the handler and web request interceptors into a single
    // array. Note that we start with the web request interceptors
    // to ensure that the OpenSessionInViewInterceptor (which is a
    // web request interceptor) is invoked before the user-defined
    // filters (which are attached to a handler interceptor). This
    // should ensure that the Hibernate session is in the proper
    // state if and when users access the database within their
    // filters.
    int j = 0;
    for (int i = 0; i < webRequestInterceptors.length; i++) {
      interceptors[j++] =
          new WebRequestHandlerInterceptorAdapter(
              (WebRequestInterceptor) webContext.getBean(webRequestInterceptors[i]));
    }
    for (int i = 0; i < interceptorNames.length; i++) {
      interceptors[j++] = (HandlerInterceptor) webContext.getBean(interceptorNames[i]);
    }
    return interceptors;
  }
  private String getBeanNameByType(WebApplicationContext wac, Class<?> endpointClass) {

    String wacId = wac.getId();

    Map<Class<?>, String> beanNamesByType = cache.get(wacId);
    if (beanNamesByType == null) {
      beanNamesByType = new ConcurrentHashMap<Class<?>, String>();
      cache.put(wacId, beanNamesByType);
    }

    if (!beanNamesByType.containsKey(endpointClass)) {
      String[] names = wac.getBeanNamesForType(endpointClass);
      if (names.length == 1) {
        beanNamesByType.put(endpointClass, names[0]);
      } else {
        beanNamesByType.put(endpointClass, NO_VALUE);
        if (names.length > 1) {
          String message =
              "Found multiple @ServerEndpoint's of type " + endpointClass + ", names=" + names;
          logger.error(message);
          throw new IllegalStateException(message);
        }
      }
    }

    String beanName = beanNamesByType.get(endpointClass);
    return NO_VALUE.equals(beanName) ? null : beanName;
  }
  /**
   * Executes Grails bootstrap classes
   *
   * @param application The Grails ApplicationContext instance
   * @param webContext The WebApplicationContext instance
   * @param servletContext The ServletContext instance
   */
  public static void executeGrailsBootstraps(
      GrailsApplication application,
      WebApplicationContext webContext,
      ServletContext servletContext) {

    PersistenceContextInterceptor interceptor = null;
    String[] beanNames = webContext.getBeanNamesForType(PersistenceContextInterceptor.class);
    if (beanNames.length > 0) {
      interceptor = (PersistenceContextInterceptor) webContext.getBean(beanNames[0]);
    }

    if (interceptor != null) {
      interceptor.init();
    }
    // init the Grails application
    try {
      GrailsClass[] bootstraps = application.getArtefacts(BootstrapArtefactHandler.TYPE);
      for (GrailsClass bootstrap : bootstraps) {
        final GrailsBootstrapClass bootstrapClass = (GrailsBootstrapClass) bootstrap;
        final Object instance = bootstrapClass.getReferenceInstance();
        webContext
            .getAutowireCapableBeanFactory()
            .autowireBeanProperties(instance, AutowireCapableBeanFactory.AUTOWIRE_BY_NAME, false);
        bootstrapClass.callInit(servletContext);
      }
      if (interceptor != null) {
        interceptor.flush();
      }
    } finally {
      if (interceptor != null) {
        interceptor.destroy();
      }
    }
  }
 @Test
 public void test() throws Exception {
   System.out.println(wac.getBeanNamesForType(SessionScopeBean.class)[0]);
   mockMvc
       .perform(get("/sessionScope/abc"))
       .andExpect(view().name("home"))
       .andExpect(
           request()
               .sessionAttribute(
                   "scopedTarget.sessionScopeBean", hasProperty("value", is("abc"))));
 }
  /**
   * Evalutes the given WebApplicationContext for all HandlerInterceptor and WebRequestInterceptor
   * instances
   *
   * @param webContext The WebApplicationContext
   * @return An array of HandlerInterceptor instances
   */
  protected HandlerInterceptor[] establishInterceptors(WebApplicationContext webContext) {
    String[] interceptorNames = webContext.getBeanNamesForType(HandlerInterceptor.class);
    String[] webRequestInterceptors = webContext.getBeanNamesForType(WebRequestInterceptor.class);
    @SuppressWarnings("hiding")
    HandlerInterceptor[] interceptors =
        new HandlerInterceptor[interceptorNames.length + webRequestInterceptors.length];

    // Merge the handler and web request interceptors into a single array. Note that we
    // start with the web request interceptors to ensure that the OpenSessionInViewInterceptor
    // (which is a web request interceptor) is invoked before the user-defined filters
    // (which are attached to a handler interceptor). This should ensure that the Hibernate
    // session is in the proper state if and when users access the database within their filters.
    int j = 0;
    for (String webRequestInterceptor : webRequestInterceptors) {
      interceptors[j++] =
          new WebRequestHandlerInterceptorAdapter(
              (WebRequestInterceptor) webContext.getBean(webRequestInterceptor));
    }
    for (String interceptorName : interceptorNames) {
      interceptors[j++] = (HandlerInterceptor) webContext.getBean(interceptorName);
    }
    return interceptors;
  }
 /**
  * Binds a Mock implementation of a GrailsWebRequest object to the current thread. The mock
  * version uses instances of the Spring MockHttpServletRequest, MockHttpServletResponse and
  * MockServletContext classes.
  *
  * @param ctx The WebApplicationContext to use
  * @see org.springframework.mock.web.MockHttpServletRequest
  * @see org.springframework.mock.web.MockHttpServletResponse
  * @see org.springframework.mock.web.MockServletContext
  * @return The GrailsWebRequest instance
  */
 public static GrailsWebRequest bindMockWebRequest(WebApplicationContext ctx) {
   MockHttpServletRequest request = new MockHttpServletRequest();
   GrailsWebRequest webRequest =
       new GrailsWebRequest(request, new MockHttpServletResponse(), ctx.getServletContext());
   request.setAttribute(GrailsApplicationAttributes.WEB_REQUEST, webRequest);
   String[] paramListenerBeans = ctx.getBeanNamesForType(ParameterCreationListener.class);
   for (String paramListenerBean : paramListenerBeans) {
     ParameterCreationListener creationListenerBean =
         (ParameterCreationListener) ctx.getBean(paramListenerBean);
     webRequest.addParameterListener(creationListenerBean);
   }
   RequestContextHolder.setRequestAttributes(webRequest);
   return webRequest;
 }