/** * Constructs a GroovyPageMetaInfo instance which holds the script class, modified date and so on * * @param inputStream The InputStream to construct the GroovyPageMetaInfo instance from * @param res The Spring Resource to construct the MetaInfo from * @param pageName The name of the page (can be null, in which case method responsible for * calculating appropriate alternative) * @return The GroovyPageMetaInfo instance */ protected GroovyPageMetaInfo buildPageMetaInfo( InputStream inputStream, Resource res, String pageName) { String name = establishPageName(res, pageName); long lastModified = establishLastModified(res); GroovyPageParser parser; String path = getPathForResource(res); try { parser = new GroovyPageParser(name, path, path, inputStream); } catch (IOException e) { throw new GroovyPagesException( "I/O parsing Groovy page [" + (res != null ? res.getDescription() : name) + "]: " + e.getMessage(), e); } InputStream in = parser.parse(); // Make a new metaInfo GroovyPageMetaInfo metaInfo = createPageMetaInfo(parser, lastModified, in); try { metaInfo.setPageClass(compileGroovyPage(in, name, path, metaInfo)); metaInfo.setHtmlParts(parser.getHtmlPartsArray()); } catch (GroovyPagesException e) { metaInfo.setCompilationException(e); } if (!name.startsWith(GENERATED_GSP_NAME_PREFIX)) { pageCache.put(name, metaInfo); } return metaInfo; }
/** * Attempts to compile the given InputStream into a Groovy script using the given name * * @param in The InputStream to read the Groovy code from * @param name The name of the class to use * @param pageName The page name * @param metaInfo * @return The compiled java.lang.Class, which is an instance of groovy.lang.Script */ private Class<?> compileGroovyPage( InputStream in, String name, String pageName, GroovyPageMetaInfo metaInfo) { GroovyClassLoader groovyClassLoader = findOrInitGroovyClassLoader(); // Compile the script into an object Class<?> scriptClass; try { scriptClass = groovyClassLoader.parseClass(DefaultGroovyMethods.getText(in), name); } catch (CompilationFailedException e) { LOG.error("Compilation error compiling GSP [" + name + "]:" + e.getMessage(), e); int lineNumber = GrailsExceptionResolver.extractLineNumber(e); final int[] lineMappings = metaInfo.getLineNumbers(); if (lineNumber > 0 && lineNumber < lineMappings.length) { lineNumber = lineMappings[lineNumber - 1]; } throw new GroovyPagesException( "Could not parse script [" + name + "]: " + e.getMessage(), e, lineNumber, pageName); } catch (IOException e) { throw new GroovyPagesException( "IO exception parsing script [" + name + "]: " + e.getMessage(), e); } return scriptClass; }
/** * 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; }
private GroovyPageTemplate createTemplateFromPrecompiled(String originalUri, String uri) { if (precompiledGspMap != null) { GroovyPageMetaInfo meta = precompiledCache.get(uri); if (meta != null) { return new GroovyPageTemplate(meta); } String gspClassName = precompiledGspMap.get(uri); if (gspClassName != null) { Class<GroovyPage> gspClass = null; try { gspClass = (Class<GroovyPage>) Class.forName(gspClassName, true, Thread.currentThread().getContextClassLoader()); } catch (ClassNotFoundException e) { LOG.warn( "Cannot load class " + gspClassName + ". Resuming on non-precompiled implementation.", e); } if (gspClass != null) { meta = new GroovyPageMetaInfo(gspClass); meta.setJspTagLibraryResolver(jspTagLibraryResolver); meta.setTagLibraryLookup(tagLibraryLookup); if (LOG.isDebugEnabled()) { LOG.debug( "Adding GSP class GroovyPageMetaInfo in cache for uri " + uri + " classname is " + gspClassName); } precompiledCache.put(uri, meta); precompiledCache.put(originalUri, meta); return new GroovyPageTemplate(meta); } } if (precompiledGspMap.size() > 0) {} if (LOG.isDebugEnabled()) { LOG.debug("No precompiled template found for uri '" + uri + "'"); } } return null; }
/** * Establishes whether a Groovy page is reloadable. A GSP is only reloadable in the development * environment. * * @param resource The Resource to check. * @param meta The current GroovyPageMetaInfo instance * @return True if it is reloadable */ private boolean isGroovyPageReloadable(Resource resource, GroovyPageMetaInfo meta) { return isReloadEnabled() && (establishLastModified(resource) > meta.getLastModified()); }