Skip to content

Commit 12d39c8

Browse files
committed
Some last-minute fixes to be included in 1.3.5 .
Performance fix to GroovyPagesTemplateEngine: enable caching for Resources by default (related to commit: http://github.com/grails/grails-core/commit/50dea0be5f4feaffdd96b0cad6765413a94d857f / GRAILS-6573) Changes related to GRAILS-5787 fix. GSP reloading works for deployed wars as documented. Restricted showSource only for development environment.
1 parent 919df0f commit 12d39c8

File tree

4 files changed

+77
-46
lines changed

4 files changed

+77
-46
lines changed

src/java/org/codehaus/groovy/grails/plugins/web/GroovyPagesGrailsPlugin.groovy

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -91,23 +91,27 @@ class GroovyPagesGrailsPlugin {
9191
boolean developmentMode = !application.warDeployed
9292
Environment env = Environment.current
9393
boolean enableReload = env.isReloadEnabled() ||
94-
application.config.grails.gsp.enable.reload == true ||
95-
Boolean.getBoolean('grails.gsp.reload.enable') ||
94+
application?.flatConfig?.get(GroovyPagesTemplateEngine.CONFIG_PROPERTY_GSP_ENABLE_RELOAD) == true ||
95+
Boolean.getBoolean(GroovyPagesTemplateEngine.CONFIG_PROPERTY_GSP_ENABLE_RELOAD) ||
9696
(developmentMode && env == Environment.DEVELOPMENT)
9797
boolean warDeployedWithReload = application.warDeployed && enableReload
98+
boolean enableCacheResources = !(application?.flatConfig?.get(GroovyPagesTemplateEngine.CONFIG_PROPERTY_DISABLE_CACHING_RESOURCES) == true)
9899

100+
boolean customResourceLoader=false
99101
// If the development environment is used we need to load GSP files relative to the base directory
100102
// as oppose to in WAR deployment where views are loaded from /WEB-INF
101103
def viewsDir = application.config.grails.gsp.view.dir
102104
if (viewsDir) {
103105
log.info "Configuring GSP views directory as '${viewsDir}'"
106+
customResourceLoader=true
104107
groovyPageResourceLoader(GroovyPageResourceLoader) {
105108
baseResource = "file:${viewsDir}"
106109
pluginSettings = new PluginBuildSettings(BuildSettingsHolder.settings)
107110
}
108111
}
109112
else {
110113
if (developmentMode) {
114+
customResourceLoader=true
111115
groovyPageResourceLoader(GroovyPageResourceLoader) { bean ->
112116
bean.lazyInit = true
113117
BuildSettings settings = BuildSettingsHolder.settings
@@ -117,15 +121,11 @@ class GroovyPagesGrailsPlugin {
117121
}
118122
}
119123
else {
120-
if (warDeployedWithReload) {
124+
if (warDeployedWithReload && env.hasReloadLocation()) {
125+
customResourceLoader=true
121126
groovyPageResourceLoader(GroovyPageResourceLoader) {
122-
if (env.hasReloadLocation()) {
123-
def location = GroovyPagesGrailsPlugin.transformToValidLocation(env.reloadLocation)
124-
baseResource = "file:${location}"
125-
}
126-
else {
127-
baseResource = "/WEB-INF"
128-
}
127+
def location = GroovyPagesGrailsPlugin.transformToValidLocation(env.reloadLocation)
128+
baseResource = "file:${location}"
129129
pluginSettings = new PluginBuildSettings(BuildSettingsHolder.settings)
130130
}
131131
}
@@ -135,7 +135,7 @@ class GroovyPagesGrailsPlugin {
135135
// Setup the main templateEngine used to render GSPs
136136
groovyPagesTemplateEngine(GroovyPagesTemplateEngine) { bean ->
137137
classLoader = ref("classLoader")
138-
if (developmentMode || warDeployedWithReload) {
138+
if (customResourceLoader) {
139139
resourceLoader = groovyPageResourceLoader
140140
bean.lazyInit = true
141141
}
@@ -148,6 +148,7 @@ class GroovyPagesGrailsPlugin {
148148
ignoreResourceNotFound = true
149149
location = "classpath:gsp/views.properties"
150150
}
151+
cacheResources = enableCacheResources
151152
}
152153

153154
// Setup the GroovyPagesUriService

src/java/org/codehaus/groovy/grails/support/ResourceAwareTemplateEngine.java

Lines changed: 38 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,23 @@
1616

1717
import groovy.text.Template;
1818
import groovy.text.TemplateEngine;
19-
import org.springframework.core.io.Resource;
2019

20+
import java.io.ByteArrayInputStream;
21+
import java.io.File;
22+
import java.io.FileInputStream;
23+
import java.io.FileNotFoundException;
2124
import java.io.IOException;
2225
import java.io.InputStream;
26+
import java.io.OutputStreamWriter;
2327
import java.io.Reader;
28+
import java.net.URL;
29+
30+
import org.apache.commons.io.IOUtils;
31+
import org.codehaus.groovy.control.CompilationFailedException;
32+
import org.codehaus.groovy.grails.web.pages.GroovyPageParser;
33+
import org.codehaus.groovy.grails.web.util.StreamByteBuffer;
34+
import org.codehaus.groovy.runtime.DefaultGroovyMethodsSupport;
35+
import org.springframework.core.io.Resource;
2436

2537
/**
2638
* An abstract TemplateEngine that extends the default Groovy TemplateEngine (@see groovy.text.TemplateEngine) and
@@ -33,8 +45,6 @@
3345
* Time: 6:37:08 PM
3446
*/
3547
abstract public class ResourceAwareTemplateEngine extends TemplateEngine {
36-
37-
3848
/**
3949
* Creates the specified Template using the given Spring Resource
4050
*
@@ -44,7 +54,7 @@ abstract public class ResourceAwareTemplateEngine extends TemplateEngine {
4454
* @throws ClassNotFoundException Thrown when there was a problem loading the Template into a class
4555
*/
4656
public Template createTemplate(Resource resource) throws IOException, ClassNotFoundException {
47-
return createTemplate(resource.getInputStream());
57+
return createTemplateAndCloseInput(resource.getInputStream());
4858
}
4959

5060
/**
@@ -56,12 +66,12 @@ public Template createTemplate(Resource resource) throws IOException, ClassNotFo
5666
* @throws IOException Thrown when there was an error reading the Template
5767
* @throws ClassNotFoundException Thrown when there was a problem loading the Template into a class
5868
*/
59-
public Template createTemplate(Resource resource, boolean cacheable) throws IOException, ClassNotFoundException {
60-
return createTemplate(resource.getInputStream());
61-
}
69+
abstract public Template createTemplate(Resource resource, boolean cacheable);
6270

6371
public final Template createTemplate(Reader reader) throws IOException {
64-
return createTemplate(new ReaderInputStream(reader));
72+
StreamByteBuffer buf=new StreamByteBuffer();
73+
IOUtils.copy(reader, new OutputStreamWriter(buf.getOutputStream(), GroovyPageParser.GROOVY_SOURCE_CHAR_ENCODING));
74+
return createTemplate(buf.getInputStream());
6575
}
6676
/**
6777
* Unlike groovy.text.TemplateEngine, implementors need to provide an implementation that operates
@@ -72,17 +82,27 @@ public final Template createTemplate(Reader reader) throws IOException {
7282
* @throws IOException Thrown when an IO error occurs reading the stream
7383
*/
7484
abstract public Template createTemplate(InputStream inputStream) throws IOException;
85+
86+
@Override
87+
public Template createTemplate(String templateText) throws CompilationFailedException, ClassNotFoundException, IOException {
88+
return createTemplate(new ByteArrayInputStream(templateText.getBytes(GroovyPageParser.GROOVY_SOURCE_CHAR_ENCODING)));
89+
}
90+
91+
@Override
92+
public Template createTemplate(File file) throws CompilationFailedException, ClassNotFoundException, IOException {
93+
return createTemplateAndCloseInput(new FileInputStream(file));
94+
}
7595

76-
// wraps a Reader in an InputStream
77-
private class ReaderInputStream extends InputStream {
78-
private Reader reader;
96+
@Override
97+
public Template createTemplate(URL url) throws CompilationFailedException, ClassNotFoundException, IOException {
98+
return createTemplateAndCloseInput(url.openStream());
99+
}
79100

80-
public ReaderInputStream(Reader reader) {
81-
this.reader = reader;
82-
}
83-
public int read() throws IOException {
84-
return reader.read();
101+
private Template createTemplateAndCloseInput(InputStream input) throws FileNotFoundException, IOException {
102+
try {
103+
return createTemplate(input);
104+
} finally {
105+
DefaultGroovyMethodsSupport.closeWithWarning(input);
85106
}
86-
}
87-
107+
}
88108
}

src/java/org/codehaus/groovy/grails/web/pages/GroovyPageMetaInfo.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ class GroovyPageMetaInfo {
7373

7474
private long latestLastModifiedCheck=0L;
7575
public static final long LASTMODIFIED_CHECK_INTERVAL = Long.getLong("grails.gsp.reload.interval", 5000).longValue();
76-
private static final long LASTMODIFIED_CHECK_GRANULARITY = Long.getLong("grails.gsp.reload.granularity", 1000).longValue();
76+
private static final long LASTMODIFIED_CHECK_GRANULARITY = Long.getLong("grails.gsp.reload.granularity", 2000).longValue();
7777

7878
public GroovyPageMetaInfo() {
7979
latestLastModifiedCheck=System.currentTimeMillis();

src/java/org/codehaus/groovy/grails/web/pages/GroovyPagesTemplateEngine.java

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,8 @@
7676
* @since 0.1
7777
*/
7878
public class GroovyPagesTemplateEngine extends ResourceAwareTemplateEngine implements ApplicationContextAware, ServletContextAware, InitializingBean {
79-
79+
public static final String CONFIG_PROPERTY_DISABLE_CACHING_RESOURCES="grails.gsp.disable.caching.resources";
80+
public static final String CONFIG_PROPERTY_GSP_ENABLE_RELOAD="grails.gsp.enable.reload";
8081
private static final String GENERATED_GSP_NAME_PREFIX = "gsp_script_";
8182
private static final Log LOG = LogFactory.getLog(GroovyPagesTemplateEngine.class);
8283
private Map<String, GroovyPageMetaInfo> pageCache = new ConcurrentHashMap<String, GroovyPageMetaInfo>();
@@ -92,6 +93,8 @@ public class GroovyPagesTemplateEngine extends ResourceAwareTemplateEngine impl
9293
private TagLibraryResolver jspTagLibraryResolver;
9394
private Map<String, String> precompiledGspMap;
9495
private Map<String, GroovyPageMetaInfo> precompiledCache = new ConcurrentHashMap<String, GroovyPageMetaInfo>();
96+
private boolean cacheResources=true;
97+
private boolean resourceLoaderDefined=false;
9598

9699
private static File dumpLineNumbersTo;
97100

@@ -149,6 +152,7 @@ public void setClassLoader(ClassLoader classLoader) {
149152
* @param resourceLoader The ResourceLoader instance
150153
*/
151154
public void setResourceLoader(ResourceLoader resourceLoader) {
155+
this.resourceLoaderDefined=(resourceLoader != null);
152156
this.resourceLoader = resourceLoader;
153157
}
154158

@@ -184,7 +188,7 @@ public int[] calculateLineNumbersForPage(@SuppressWarnings("unused") ServletCont
184188
*/
185189
@Override
186190
public Template createTemplate(Resource resource) {
187-
return createTemplate(resource, false);
191+
return createTemplate(resource, cacheResources);
188192
}
189193

190194
/**
@@ -225,7 +229,7 @@ else if (LOG.isInfoEnabled()) {
225229
}
226230
}
227231

228-
if (pageCache.containsKey(name)&& cacheable) {
232+
if (cacheable && pageCache.containsKey(name)) {
229233
GroovyPageMetaInfo meta = pageCache.get(name);
230234

231235
if (isGroovyPageReloadable(resource, meta)) {
@@ -255,15 +259,11 @@ else if (LOG.isInfoEnabled()) {
255259
*/
256260
@Override
257261
public Template createTemplate(String uri) {
258-
Template t = createTemplateFromPrecompiled(uri);
259-
if (t == null) {
260-
t = createTemplate(getResourceForUri(uri));
261-
}
262-
return t;
262+
return createTemplateForUri(uri);
263263
}
264264

265265
private boolean isPrecompiledAvailable() {
266-
return precompiledGspMap != null && precompiledGspMap.size() > 0;
266+
return precompiledGspMap != null && precompiledGspMap.size() > 0 && !GrailsUtil.isDevelopmentEnv();
267267
}
268268

269269
private GroovyPageTemplate createTemplateFromPrecompiled(String uri) {
@@ -370,7 +370,7 @@ public Template createTemplateForUri(String[] uri) {
370370
LOG.warn("Precompiled GSP not found for uri: " + Arrays.asList(uri) + ". Using resource " + resource);
371371
}
372372
}
373-
return createTemplate(resource);
373+
return createTemplate(resource,true);
374374
}
375375
return null;
376376
}
@@ -549,13 +549,15 @@ private Resource getResourceForUri(String uri) {
549549

550550
private Resource getResourceWithinContext(String uri) {
551551
Assert.state(resourceLoader != null, "TemplateEngine not initialised correctly, no [resourceLoader] specified!");
552-
if (Environment.getCurrent().isReloadEnabled() && Metadata.getCurrent().isWarDeployed()) {
552+
if (resourceLoaderDefined) {
553553
return resourceLoader.getResource(uri);
554554
}
555-
556555
Resource r = servletContextLoader.getResource(uri);
557-
if (r.exists()) return r;
558-
return resourceLoader.getResource(uri);
556+
if (r.exists()) {
557+
return r;
558+
} else {
559+
return resourceLoader.getResource(uri);
560+
}
559561
}
560562

561563

@@ -635,7 +637,7 @@ private Class<?> compileGroovyPage(InputStream in, String name, String pageName,
635637
// Compile the script into an object
636638
Class<?> scriptClass;
637639
try {
638-
scriptClass = groovyClassLoader.parseClass(DefaultGroovyMethods.getText(in), name);
640+
scriptClass = groovyClassLoader.parseClass(DefaultGroovyMethods.getText(in, GroovyPageParser.GROOVY_SOURCE_CHAR_ENCODING), name);
639641
}
640642
catch (CompilationFailedException e) {
641643
LOG.error("Compilation error compiling GSP ["+name+"]:" + e.getMessage(), e);
@@ -680,7 +682,7 @@ private GroovyPageMetaInfo createPageMetaInfo(GroovyPageParser parse, InputStrea
680682
pageMeta.setCodecName(parse.getDefaultCodecDirectiveValue());
681683
pageMeta.initCodec();
682684
// just return groovy and don't compile if asked
683-
if (isReloadEnabled() || GrailsUtil.isDevelopmentEnv()) {
685+
if (GrailsUtil.isDevelopmentEnv()) {
684686
pageMeta.setGroovySource(in);
685687
}
686688

@@ -818,4 +820,12 @@ public Map<String, String> getPrecompiledGspMap() {
818820
public void setPrecompiledGspMap(Map<String, String> precompiledGspMap) {
819821
this.precompiledGspMap = precompiledGspMap;
820822
}
823+
824+
public boolean isCacheResources() {
825+
return cacheResources;
826+
}
827+
828+
public void setCacheResources(boolean cacheResources) {
829+
this.cacheResources = cacheResources;
830+
}
821831
}

0 commit comments

Comments
 (0)