Skip to content

Commit

Permalink
fix for GRAILS-6573 "GroovyPagesTemplateEngine now allowing to cache …
Browse files Browse the repository at this point in the history
…Page when createTemplate(Resource) is called"
  • Loading branch information
graemerocher committed Sep 28, 2010
1 parent 1dd5d41 commit 50dea0b
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 15 deletions.
Expand Up @@ -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
* <p/>
* 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
Expand All @@ -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();
}
}

}
Expand Up @@ -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
Expand All @@ -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);
Expand All @@ -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);
Expand Down Expand Up @@ -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();
Expand Down

0 comments on commit 50dea0b

Please sign in to comment.