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; }
@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; }
@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; } }