From 50dea0be5f4feaffdd96b0cad6765413a94d857f Mon Sep 17 00:00:00 2001 From: Graeme Rocher Date: Tue, 28 Sep 2010 11:50:33 +0200 Subject: [PATCH] fix for GRAILS-6573 "GroovyPagesTemplateEngine now allowing to cache Page when createTemplate(Resource) is called" --- .../support/ResourceAwareTemplateEngine.java | 31 +++++++++---- .../web/pages/GroovyPagesTemplateEngine.java | 43 ++++++++++++++++--- 2 files changed, 59 insertions(+), 15 deletions(-) diff --git a/src/java/org/codehaus/groovy/grails/support/ResourceAwareTemplateEngine.java b/src/java/org/codehaus/groovy/grails/support/ResourceAwareTemplateEngine.java index 144bcafd29c..259a09626c8 100644 --- a/src/java/org/codehaus/groovy/grails/support/ResourceAwareTemplateEngine.java +++ b/src/java/org/codehaus/groovy/grails/support/ResourceAwareTemplateEngine.java @@ -16,42 +16,56 @@ import groovy.text.Template; import groovy.text.TemplateEngine; +import org.springframework.core.io.Resource; import java.io.IOException; import java.io.InputStream; import java.io.Reader; -import org.springframework.core.io.Resource; - /** * An abstract TemplateEngine that extends the default Groovy TemplateEngine (@see groovy.text.TemplateEngine) and * provides the ability to create templates from the Spring Resource API * * @author Graeme Rocher * @since 0.4 + *

+ * Created: Feb 22, 2007 + * Time: 6:37:08 PM */ abstract public class ResourceAwareTemplateEngine extends TemplateEngine { + /** - * Creates the specified Template using the given Spring Resource. + * Creates the specified Template using the given Spring Resource + * + * @param resource The Spring Resource to create the template for + * @return A Template instance + * @throws IOException Thrown when there was an error reading the Template + * @throws ClassNotFoundException Thrown when there was a problem loading the Template into a class + */ + public Template createTemplate(Resource resource) throws IOException, ClassNotFoundException { + return createTemplate(resource.getInputStream()); + } + + /** + * Creates the specified Template using the given Spring Resource * * @param resource The Spring Resource to create the template for + * @param cacheable Whether the resource can be cached * @return A Template instance * @throws IOException Thrown when there was an error reading the Template * @throws ClassNotFoundException Thrown when there was a problem loading the Template into a class */ - public Template createTemplate(Resource resource) throws IOException { + public Template createTemplate(Resource resource, boolean cacheable) throws IOException, ClassNotFoundException { return createTemplate(resource.getInputStream()); } - @Override public final Template createTemplate(Reader reader) throws IOException { return createTemplate(new ReaderInputStream(reader)); } - /** * Unlike groovy.text.TemplateEngine, implementors need to provide an implementation that operates - * with an InputStream. + * with an InputStream * * @param inputStream The InputStream * @return A Template instance @@ -66,10 +80,9 @@ private class ReaderInputStream extends InputStream { public ReaderInputStream(Reader reader) { this.reader = reader; } - - @Override public int read() throws IOException { return reader.read(); } } + } diff --git a/src/java/org/codehaus/groovy/grails/web/pages/GroovyPagesTemplateEngine.java b/src/java/org/codehaus/groovy/grails/web/pages/GroovyPagesTemplateEngine.java index fb3ec50bc51..3199a77a5b0 100644 --- a/src/java/org/codehaus/groovy/grails/web/pages/GroovyPagesTemplateEngine.java +++ b/src/java/org/codehaus/groovy/grails/web/pages/GroovyPagesTemplateEngine.java @@ -184,11 +184,35 @@ public int[] calculateLineNumbersForPage(@SuppressWarnings("unused") ServletCont */ @Override public Template createTemplate(Resource resource) { + return createTemplate(resource, false); + } + + /** + * Creates a Template for the given Spring Resource instance + * + * @param resource The Resource to create the Template for + * @param cacheable The resource can be cached or not + * @return The Template instance + */ + @Override + public Template createTemplate(Resource resource, boolean cacheable) { if (resource == null) { GrailsWebRequest webRequest = getWebRequest(); throw new GroovyPagesException("No Groovy page found for URI: " + getCurrentRequestUri(webRequest.getCurrentRequest())); } - String name = establishPageName(resource, null); + //Yags: Because, "pageName" was sent as null originally, it is never go in pageCache, but will force to compile the String again and till the time this request + // is getting executed, it will occupy space in PermGen space. So if there are 1000 request for the same resource at a particular instance, there will be 1000 instance + // class in PermGen instead of ideally being 1 as they as essentially same resource. + String name; + + //we will cache metaInfo only is Developer wants-to. Developer will make sure that he creates unique key for every unique pages s/he wants to put in cache + if(cacheable) { + name = establishPageName(resource, getPathForResource(resource)); + + } else { + name = establishPageName(resource, null); + } + if (!isReloadEnabled()) { // presumably war deployed mode, but precompiled gsp isn't used, log this for debugging @@ -201,12 +225,12 @@ else if (LOG.isInfoEnabled()) { } } - if (pageCache.containsKey(name)) { + if (pageCache.containsKey(name)&& cacheable) { GroovyPageMetaInfo meta = pageCache.get(name); if (isGroovyPageReloadable(resource, meta)) { try { - return createTemplateWithResource(resource, name); + return createTemplateWithResource(resource, cacheable); } catch (IOException e) { throw new GroovyPagesException("I/O error reading stream for resource ["+resource+"]: " + e.getMessage(),e); @@ -215,7 +239,7 @@ else if (LOG.isInfoEnabled()) { return new GroovyPageTemplate(meta); } try { - return createTemplateWithResource(resource, name); + return createTemplateWithResource(resource, cacheable); } catch (IOException e) { throw new GroovyPagesException("I/O error reading stream for resource ["+resource+"]: " + e.getMessage(),e); @@ -440,10 +464,17 @@ public Template createTemplate(InputStream inputStream) { * @return A Groovy Template * @throws java.io.IOException Thrown when an error occurs reading the template */ - private Template createTemplateWithResource(Resource resource, String pageName) throws IOException { + private Template createTemplateWithResource(Resource resource, boolean cacheable) throws IOException { InputStream in = resource.getInputStream(); try { - return createTemplate(in, resource, pageName); + // If "pageName" will be passed null, it will be determined by "establishPageName" method which will + // make it such that it will not allow this template to get into the pageCache. + if(cacheable) { + return createTemplate(in, resource, getPathForResource(resource)); + } else { + return createTemplate(in, resource, null); + } + } finally { in.close();