public void rebuild() {
    initialised = false;
    loadedClasses.clear();
    initArtefactHandlers();

    if (GrailsUtil.isDevelopmentEnv()) {
      initialise();
    } else {
      throw new IllegalStateException(
          "Cannot rebuild GrailsApplication when not in development mode!");
    }
  }
  /**
   * Creates a GroovyPageMetaInfo instance from the given Parse object, and initialises it with the
   * the specified last modifed date and InputStream
   *
   * @param parse The Parse object
   * @param lastModified The last modified date
   * @param in The InputStream instance
   * @return A GroovyPageMetaInfo instance
   */
  private GroovyPageMetaInfo createPageMetaInfo(
      GroovyPageParser parse, long lastModified, InputStream in) {
    GroovyPageMetaInfo pageMeta = new GroovyPageMetaInfo();
    pageMeta.setJspTagLibraryResolver(jspTagLibraryResolver);
    pageMeta.setTagLibraryLookup(tagLibraryLookup);
    pageMeta.setContentType(parse.getContentType());
    pageMeta.setLineNumbers(parse.getLineNumberMatrix());
    pageMeta.setLastModified(lastModified);
    pageMeta.setJspTags(parse.getJspTags());
    pageMeta.setCodecName(parse.getDefaultCodecDirectiveValue());
    pageMeta.initCodec();
    // just return groovy and don't compile if asked
    if (isReloadEnabled() || GrailsUtil.isDevelopmentEnv()) {
      pageMeta.setGroovySource(in);
    }

    return pageMeta;
  }
예제 #3
0
  @Override
  protected View loadView(String viewName, Locale locale) throws Exception {
    Assert.notNull(templateEngine, "Property [templateEngine] cannot be null");

    if (GrailsUtil.isDevelopmentEnv()) {
      return createGrailsView(viewName);
    }

    View view = VIEW_CACHE.get(viewName);
    if (view == null
        || (templateEngine.isReloadEnabled()
            && view instanceof GroovyPageView
            && ((GroovyPageView) view).isExpired())) {
      view = createGrailsView(viewName);
    }
    VIEW_CACHE.put(viewName, view);
    return view;
  }
  /** Default constructor. */
  public ReloadAwareAutowireCapableBeanFactory() {
    reloadEnabled = GrailsUtil.isDevelopmentEnv() || Environment.getCurrent().isReloadEnabled();
    if (reloadEnabled) {

      // Implementation note: The default Spring InstantiationStrategy caches constructors.
      // This is no good at development time because if the class reloads then Spring
      // continues to use the old class. We deal with this here by disabling the caching
      // for development time only
      setInstantiationStrategy(
          new CglibSubclassingInstantiationStrategy() {
            @Override
            public Object instantiate(
                RootBeanDefinition beanDefinition, String beanName, BeanFactory owner) {
              // Don't override the class with CGLIB if no overrides.
              if (beanDefinition.getMethodOverrides().isEmpty()) {
                Constructor<?> constructorToUse;
                Class<?> clazz = beanDefinition.getBeanClass();
                if (clazz.isInterface()) {
                  throw new BeanInstantiationException(clazz, "Specified class is an interface");
                }
                try {
                  constructorToUse = clazz.getDeclaredConstructor((Class[]) null);
                } catch (Exception ex) {
                  throw new BeanInstantiationException(clazz, "No default constructor found", ex);
                }

                return BeanUtils.instantiateClass(constructorToUse);
              }
              // Must generate CGLIB subclass.
              return instantiateWithMethodInjection(beanDefinition, beanName, owner);
            }
          });
    }

    setParameterNameDiscoverer(new LocalVariableTableParameterNameDiscoverer());
    setAutowireCandidateResolver(new QualifierAnnotationAutowireCandidateResolver());
    ignoreDependencyType(Closure.class);
  }
  /**
   * Overrides the default behaviour to establish the handler from the GrailsApplication instance
   *
   * @param request The request
   * @param cache Whether to cache the Handler in the request
   * @return The HandlerExecutionChain
   * @throws Exception
   */
  protected HandlerExecutionChain getHandler(HttpServletRequest request, boolean cache)
      throws Exception {
    String uri = urlHelper.getPathWithinApplication(request);
    if (logger.isDebugEnabled()) {
      logger.debug("Looking up Grails controller for URI [" + uri + "]");
    }
    GrailsControllerClass controllerClass =
        (GrailsControllerClass)
            application.getArtefactForFeature(ControllerArtefactHandler.TYPE, uri);
    final String actionName =
        (String) request.getAttribute(GrailsApplicationAttributes.ACTION_NAME_ATTRIBUTE);

    if (controllerClass != null) {
      HandlerInterceptor[] interceptors;
      // if we're in a development environment we want to re-establish interceptors just in case
      // they
      // have changed at runtime

      if (GrailsUtil.isDevelopmentEnv()) {
        interceptors = establishInterceptors(getWebApplicationContext());
      } else {
        interceptors = this.interceptors;
      }
      if (controllerClass.isFlowAction(actionName)) {
        FlowHandler flowHandler =
            new AbstractFlowHandler() {
              public String getFlowId() {
                return actionName;
              }
            };
        return new HandlerExecutionChain(flowHandler, interceptors);
      } else {
        return new HandlerExecutionChain(mainController, interceptors);
      }
    }
    return null;
  }
예제 #6
0
  @SuppressWarnings("unchecked")
  private void evaluateOnChangeListener() {
    if (pluginBean.isReadableProperty(ON_SHUTDOWN)) {
      onShutdownListener =
          (Closure) GrailsClassUtils.getPropertyOrStaticPropertyOrFieldValue(plugin, ON_SHUTDOWN);
    }
    if (pluginBean.isReadableProperty(ON_CONFIG_CHANGE)) {
      onConfigChangeListener =
          (Closure)
              GrailsClassUtils.getPropertyOrStaticPropertyOrFieldValue(plugin, ON_CONFIG_CHANGE);
    }
    if (pluginBean.isReadableProperty(ON_CHANGE)) {
      onChangeListener =
          (Closure) GrailsClassUtils.getPropertyOrStaticPropertyOrFieldValue(plugin, ON_CHANGE);
    }

    final boolean warDeployed = Metadata.getCurrent().isWarDeployed();
    final boolean reloadEnabled = Environment.getCurrent().isReloadEnabled();

    if (!((reloadEnabled || !warDeployed) && onChangeListener != null)) {
      return;
    }

    Object referencedResources =
        GrailsClassUtils.getPropertyOrStaticPropertyOrFieldValue(plugin, WATCHED_RESOURCES);

    try {
      List resourceList = null;
      if (referencedResources instanceof String) {
        if (LOG.isDebugEnabled()) {
          LOG.debug(
              "Configuring plugin "
                  + this
                  + " to watch resources with pattern: "
                  + referencedResources);
        }
        resourceList = new ArrayList();
        resourceList.add(referencedResources.toString());
      } else if (referencedResources instanceof List) {
        resourceList = (List) referencedResources;
      }

      if (resourceList != null) {
        List<String> resourceListTmp = new ArrayList<String>();
        PluginBuildSettings pluginBuildSettings = GrailsPluginUtils.getPluginBuildSettings();

        if (pluginBuildSettings != null) {

          final Resource[] pluginDirs = pluginBuildSettings.getPluginDirectories();
          final Environment env = Environment.getCurrent();
          final String baseLocation = env.getReloadLocation();

          for (Object ref : resourceList) {
            String stringRef = ref.toString();
            if (!warDeployed) {
              for (Resource pluginDir : pluginDirs) {
                if (pluginDir != null) {
                  String pluginResources =
                      getResourcePatternForBaseLocation(
                          pluginDir.getFile().getCanonicalPath(), stringRef);
                  resourceListTmp.add(pluginResources);
                }
              }
              addBaseLocationPattern(resourceListTmp, baseLocation, stringRef);
            } else {
              addBaseLocationPattern(resourceListTmp, baseLocation, stringRef);
            }
          }

          watchedResourcePatternReferences = new String[resourceListTmp.size()];
          for (int i = 0; i < watchedResourcePatternReferences.length; i++) {
            String resRef = resourceListTmp.get(i);
            watchedResourcePatternReferences[i] = resRef;
          }

          watchedResourcePatterns =
              new WatchPatternParser()
                  .getWatchPatterns(Arrays.asList(watchedResourcePatternReferences));
        }
      }
    } catch (IllegalArgumentException e) {
      if (GrailsUtil.isDevelopmentEnv()) {
        LOG.debug(
            "Cannot load plug-in resource watch list from ["
                + ArrayUtils.toString(watchedResourcePatternReferences)
                + "]. This means that the plugin "
                + this
                + ", will not be able to auto-reload changes effectively. Try runnng grails upgrade.: "
                + e.getMessage());
      }
    } catch (IOException e) {
      if (GrailsUtil.isDevelopmentEnv()) {
        LOG.debug(
            "Cannot load plug-in resource watch list from ["
                + ArrayUtils.toString(watchedResourcePatternReferences)
                + "]. This means that the plugin "
                + this
                + ", will not be able to auto-reload changes effectively. Try runnng grails upgrade.: "
                + e.getMessage());
      }
    }
  }
/**
 * Evaluates the existance of a view for different extensions choosing which one to delegate to.
 *
 * @author Graeme Rocher
 * @since 0.1
 */
public class GroovyPageViewResolver extends InternalResourceViewResolver
    implements GrailsViewResolver {
  private static final Log LOG = LogFactory.getLog(GroovyPageViewResolver.class);

  public static final String GSP_SUFFIX = ".gsp";
  public static final String JSP_SUFFIX = ".jsp";

  protected GroovyPagesTemplateEngine templateEngine;
  protected GrailsConventionGroovyPageLocator groovyPageLocator;

  private ConcurrentMap<String, CacheEntry<View>> viewCache =
      new ConcurrentHashMap<String, CacheEntry<View>>();
  private boolean allowGrailsViewCaching = !GrailsUtil.isDevelopmentEnv();
  private long cacheTimeout = -1;

  /** Constructor. */
  public GroovyPageViewResolver() {
    setCache(false);
    setOrder(Ordered.LOWEST_PRECEDENCE - 20);
  }

  public GroovyPageViewResolver(
      GroovyPagesTemplateEngine templateEngine,
      GrailsConventionGroovyPageLocator groovyPageLocator) {
    this();
    this.templateEngine = templateEngine;
    this.groovyPageLocator = groovyPageLocator;
  }

  public void setGroovyPageLocator(GrailsConventionGroovyPageLocator groovyPageLocator) {
    this.groovyPageLocator = groovyPageLocator;
  }

  @Override
  public View resolveViewName(String viewName, Locale locale) throws Exception {
    return super.resolveViewName(WebUtils.addViewPrefix(viewName), locale);
  }

  @Override
  protected View loadView(String viewName, Locale locale) throws Exception {
    Assert.notNull(templateEngine, "Property [templateEngine] cannot be null");
    if (viewName.endsWith(GSP_SUFFIX)) {
      viewName = viewName.substring(0, viewName.length() - GSP_SUFFIX.length());
    }

    if (!allowGrailsViewCaching) {
      return createGrailsView(viewName);
    }

    String viewCacheKey = groovyPageLocator.resolveViewFormat(viewName);

    String currentControllerKeyPrefix = resolveCurrentControllerKeyPrefixes();
    if (currentControllerKeyPrefix != null) {
      viewCacheKey = currentControllerKeyPrefix + ':' + viewCacheKey;
    }

    CacheEntry<View> entry = viewCache.get(viewCacheKey);

    final String lookupViewName = viewName;
    Callable<View> updater =
        new Callable<View>() {
          public View call() throws Exception {
            try {
              return createGrailsView(lookupViewName);
            } catch (Exception e) {
              throw new WrappedInitializationException(e);
            }
          }
        };

    View view = null;
    if (entry == null) {
      try {
        return CacheEntry.getValue(viewCache, viewCacheKey, cacheTimeout, updater);
      } catch (CacheEntry.UpdateException e) {
        e.rethrowCause();
        // make compiler happy
        return null;
      }
    }

    try {
      view = entry.getValue(cacheTimeout, updater, true, null);
    } catch (WrappedInitializationException e) {
      e.rethrowCause();
    }

    return view;
  }

  /**
   * @return prefix for cache key that contains current controller's context (currently plugin and
   *     namespace)
   */
  protected String resolveCurrentControllerKeyPrefixes() {
    String pluginContextPath = null;
    String namespace = null;
    GrailsWebRequest webRequest = GrailsWebRequest.lookup();
    if (webRequest != null) {
      namespace = webRequest.getControllerNamespace();
      pluginContextPath =
          (webRequest.getAttributes() != null && webRequest.getCurrentRequest() != null)
              ? webRequest.getAttributes().getPluginContextPath(webRequest.getCurrentRequest())
              : null;
      return (pluginContextPath != null ? pluginContextPath : "-")
          + ","
          + (namespace != null ? namespace : "-");
    } else {
      return null;
    }
  }

  private static class WrappedInitializationException extends RuntimeException {
    private static final long serialVersionUID = 1L;

    public WrappedInitializationException(Throwable cause) {
      super(cause);
    }

    public void rethrowCause() throws Exception {
      if (getCause() instanceof Exception) {
        throw (Exception) getCause();
      }

      throw this;
    }
  }

  protected View createGrailsView(String viewName) throws Exception {
    // try GSP if res is null

    GroovyObject controller = null;

    GrailsWebRequest webRequest = GrailsWebRequest.lookup();
    if (webRequest != null) {
      HttpServletRequest request = webRequest.getCurrentRequest();
      controller = webRequest.getAttributes().getController(request);
    }

    GroovyPageScriptSource scriptSource;
    if (controller == null) {
      scriptSource = groovyPageLocator.findViewByPath(viewName);
    } else {
      scriptSource = groovyPageLocator.findView(controller, viewName);
    }
    if (scriptSource != null) {
      return createGroovyPageView(scriptSource.getURI(), scriptSource);
    }

    return createFallbackView(viewName);
  }

  private View createGroovyPageView(String gspView, ScriptSource scriptSource) {
    if (LOG.isDebugEnabled()) {
      LOG.debug("Resolved GSP view at URI [" + gspView + "]");
    }
    GroovyPageView gspSpringView = new GroovyPageView();
    gspSpringView.setServletContext(getServletContext());
    gspSpringView.setUrl(gspView);
    gspSpringView.setApplicationContext(getApplicationContext());
    gspSpringView.setTemplateEngine(templateEngine);
    gspSpringView.setScriptSource(scriptSource);
    try {
      gspSpringView.afterPropertiesSet();
    } catch (Exception e) {
      throw new RuntimeException("Error initializing GroovyPageView", e);
    }
    return gspSpringView;
  }

  protected View createFallbackView(String viewName) throws Exception {
    return createJstlView(viewName);
  }

  protected View createJstlView(String viewName) throws Exception {
    AbstractUrlBasedView view = buildView(viewName);
    view.setApplicationContext(getApplicationContext());
    view.afterPropertiesSet();
    return view;
  }

  @Autowired(required = true)
  @Qualifier(GroovyPagesTemplateEngine.BEAN_ID)
  public void setTemplateEngine(GroovyPagesTemplateEngine templateEngine) {
    this.templateEngine = templateEngine;
  }

  public long getCacheTimeout() {
    return cacheTimeout;
  }

  public void setCacheTimeout(long cacheTimeout) {
    this.cacheTimeout = cacheTimeout;
  }

  @Override
  public void clearCache() {
    super.clearCache();
    viewCache.clear();
  }

  public boolean isAllowGrailsViewCaching() {
    return allowGrailsViewCaching;
  }

  public void setAllowGrailsViewCaching(boolean allowGrailsViewCaching) {
    this.allowGrailsViewCaching = allowGrailsViewCaching;
  }
}