Skip to content

Commit 54825fc

Browse files
committed
Ensure pre-compiled GSPs honor settings in application.yml. Fixes #9956
1 parent c3732ab commit 54825fc

File tree

11 files changed

+160
-125
lines changed

11 files changed

+160
-125
lines changed

grails-bootstrap/src/main/groovy/grails/config/ConfigMap.groovy

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,15 @@ interface ConfigMap extends Iterable<Map.Entry<String, Object>>, Map<String, Obj
4747
*/
4848
def <T> T getProperty(String key, Class<T> targetType)
4949

50+
/**
51+
* Return the property value associated with the given key, or {@code null}
52+
* if the key cannot be resolved.
53+
* @param key the property name to resolve
54+
* @param targetType the expected type of the property value
55+
* @see #getRequiredProperty(String, Class)
56+
*/
57+
def <T> T getProperty(String key, Class<T> targetType, T defaultValue)
58+
5059
/**
5160
* Return the property value associated with the given key, converted to the given
5261
* targetType (never {@code null}).

grails-bootstrap/src/main/groovy/grails/util/Metadata.groovy

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,15 @@ public class Metadata extends NavigableMap implements ConfigMap {
353353
return get(key)?.asType(targetType)
354354
}
355355

356+
@Override
357+
def <T> T getProperty(String key, Class<T> targetType, T defaultValue) {
358+
def v = getProperty(key, targetType)
359+
if(v == null) {
360+
return defaultValue
361+
}
362+
return v
363+
}
364+
356365
@Override
357366
def <T> T getRequiredProperty(String key, Class<T> targetType) throws IllegalStateException {
358367
def value = get(key)

grails-bootstrap/src/main/groovy/org/grails/config/CodeGenConfig.groovy

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,15 @@ class CodeGenConfig implements Cloneable, ConfigMap {
138138
}
139139
}
140140

141+
void loadGroovy(File groovyConfig) {
142+
if(groovyConfig.exists()) {
143+
def envName = Environment.current.name
144+
def configSlurper = new ConfigSlurper(envName)
145+
def configObject = configSlurper.parse(groovyConfig.toURI().toURL())
146+
mergeMap(configObject, false)
147+
}
148+
}
149+
141150
@CompileDynamic // fails with CompileStatic!
142151
void loadYml(InputStream input) {
143152
Yaml yaml = new Yaml()
@@ -251,7 +260,16 @@ class CodeGenConfig implements Cloneable, ConfigMap {
251260
public <T> T getProperty(String name, Class<T> requiredType) {
252261
return convertToType( configMap.getProperty(name), requiredType )
253262
}
254-
263+
264+
@Override
265+
def <T> T getProperty(String key, Class<T> targetType, T defaultValue) {
266+
def v = getProperty(key, targetType)
267+
if(v == null) {
268+
return defaultValue
269+
}
270+
return v
271+
}
272+
255273
public void setProperty(String name, Object value) {
256274
configMap.setProperty(name, value)
257275
}

grails-gradle-plugin/src/main/groovy/org/grails/gradle/plugin/web/gsp/GroovyPageCompileTask.groovy

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,10 @@ class GroovyPageCompileTask extends AbstractCompile {
6666
packagename: packagename,
6767
serverpath: serverpath,
6868
tmpdir: tmpdir) {
69+
delegate.configs {
70+
pathelement(path: gradleProject.file('grails-app/conf/application.yml').absolutePath)
71+
pathelement(path: gradleProject.file('grails-app/conf/application.groovy').absolutePath)
72+
}
6973
delegate.classpath {
7074
pathelement(path: dest.absolutePath)
7175
pathelement(path: compileTask.classpath.asPath)

grails-gsp/src/main/groovy/org/grails/gsp/GroovyPagesTemplateEngine.java

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
import grails.util.CacheEntry;
2424
import grails.util.Environment;
2525
import grails.util.GrailsUtil;
26-
import grails.util.Holders;
2726
import groovy.lang.GroovyClassLoader;
2827
import groovy.text.Template;
2928
import org.apache.commons.logging.Log;
@@ -38,6 +37,7 @@
3837
import org.grails.gsp.io.*;
3938
import org.grails.gsp.jsp.TagLibraryResolver;
4039
import org.grails.taglib.TagLibraryLookup;
40+
import org.grails.taglib.encoder.OutputEncodingSettings;
4141
import org.springframework.beans.BeansException;
4242
import org.springframework.beans.factory.BeanClassLoaderAware;
4343
import org.springframework.beans.factory.InitializingBean;
@@ -96,6 +96,7 @@ public class GroovyPagesTemplateEngine extends ResourceAwareTemplateEngine imple
9696
private TagLibraryLookup tagLibraryLookup;
9797
private TagLibraryResolver jspTagLibraryResolver;
9898
private boolean cacheResources = true;
99+
private String gspEncoding = System.getProperty("file.encoding", GroovyPageParser.DEFAULT_ENCODING);
99100

100101
private GrailsApplication grailsApplication;
101102
private Map<String, Class<?>> cachedDomainsWithoutPackage;
@@ -527,19 +528,12 @@ protected GroovyPageMetaInfo buildPageMetaInfo(InputStream inputStream, Resource
527528
GroovyPageParser parser;
528529
String path = getPathForResource(res);
529530
try {
530-
String gspSource = IOUtils.toString(inputStream, GroovyPageParser.getGspEncoding());
531+
String gspSource = IOUtils.toString(inputStream, getGspEncoding());
531532
parser = new GroovyPageParser(name, path, path, decorateGroovyPageSource(new StringBuilder(gspSource)).toString());
532533

533534
if (grailsApplication != null) {
534535
Config config = grailsApplication.getConfig();
535-
536-
Object keepDirObj = config.getProperty(GroovyPageParser.CONFIG_PROPERTY_GSP_KEEPGENERATED_DIR, Object.class);
537-
if (keepDirObj instanceof File) {
538-
parser.setKeepGeneratedDirectory((File) keepDirObj);
539-
}
540-
else if (keepDirObj != null) {
541-
parser.setKeepGeneratedDirectory(new File(String.valueOf(keepDirObj)));
542-
}
536+
parser.configure(config);
543537
}
544538
}
545539
catch (IOException e) {
@@ -720,6 +714,8 @@ private String generateTemplateName() {
720714
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
721715
if (applicationContext.containsBean(GrailsApplication.APPLICATION_ID)) {
722716
this.grailsApplication = applicationContext.getBean(GrailsApplication.APPLICATION_ID, GrailsApplication.class);
717+
Config config = grailsApplication.getConfig();
718+
this.gspEncoding = config.getProperty(GroovyPageParser.CONFIG_PROPERTY_GSP_ENCODING, System.getProperty("file.encoding", GroovyPageParser.DEFAULT_ENCODING));
723719
}
724720
}
725721

@@ -811,10 +807,6 @@ public void setBeanClassLoader(ClassLoader beanClassLoader) {
811807
}
812808

813809
public String getGspEncoding() {
814-
Config config = Holders.getConfig();
815-
if (config != null) {
816-
return config.getProperty(GroovyPageParser.CONFIG_PROPERTY_GSP_ENCODING, System.getProperty("file.encoding", "us-ascii"));
817-
}
818-
return System.getProperty("file.encoding", "us-ascii");
810+
return this.gspEncoding;
819811
}
820812
}

grails-gsp/src/main/groovy/org/grails/gsp/compiler/GroovyPageCompiler.groovy

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,17 @@
1414
* limitations under the License.
1515
*/
1616
package org.grails.gsp.compiler
17+
18+
import grails.config.ConfigMap
1719
import org.apache.commons.logging.LogFactory
1820
import org.codehaus.groovy.control.CompilationUnit
1921
import org.codehaus.groovy.control.CompilerConfiguration
2022
import org.codehaus.groovy.control.Phases
23+
import org.grails.config.CodeGenConfig
2124
import org.grails.gsp.GroovyPageMetaInfo
2225
import org.grails.gsp.compiler.transform.GroovyPageInjectionOperation
26+
import org.grails.taglib.encoder.OutputEncodingSettings
27+
2328
/**
2429
* Used to compile GSP files into a specified target directory.
2530
*
@@ -43,6 +48,9 @@ class GroovyPageCompiler {
4348
String viewPrefix = '/'
4449
String packagePrefix = 'default'
4550
String encoding = "UTF-8"
51+
String expressionCodec = OutputEncodingSettings.getDefaultValue(OutputEncodingSettings.EXPRESSION_CODEC_NAME)
52+
String[] configs = []
53+
ConfigMap configMap
4654

4755
void setCompilerConfig(CompilerConfiguration c) {
4856
compilerConfig = c
@@ -60,6 +68,22 @@ class GroovyPageCompiler {
6068
Map compile() {
6169
if (srcFiles && targetDir && viewsDir) {
6270
LOG.debug "Compiling ${srcFiles.size()} GSP files using GroovyPageCompiler"
71+
72+
if(configs) {
73+
def codeGenConfig = new CodeGenConfig()
74+
configMap = codeGenConfig
75+
for(path in configs) {
76+
def f = new File(path)
77+
if(f.exists()) {
78+
if(f.name.endsWith('.yml')) {
79+
codeGenConfig.loadYml(f)
80+
}
81+
else if(f.name.endsWith('.groovy')) {
82+
codeGenConfig.loadGroovy(f)
83+
}
84+
}
85+
}
86+
}
6387
for (gsp in srcFiles) {
6488
compileGSP(viewsDir, gsp, viewPrefix, packagePrefix)
6589
}
@@ -122,10 +146,13 @@ class GroovyPageCompiler {
122146
gspgroovyfile.getParentFile().mkdirs()
123147

124148
gspfile.withInputStream { InputStream gspinput ->
125-
GroovyPageParser gpp = new GroovyPageParser(viewuri - '.gsp', viewuri, gspfile.absolutePath, gspinput)
149+
GroovyPageParser gpp = new GroovyPageParser(viewuri - '.gsp', viewuri, gspfile.absolutePath, gspinput, encoding, expressionCodec)
126150
gpp.packageName = packageName
127151
gpp.className = className
128152
gpp.lastModified = gspfile.lastModified()
153+
if(configMap) {
154+
gpp.configure(configMap)
155+
}
129156
gspgroovyfile.withWriter(encoding) { Writer gsptarget ->
130157
// generate gsp groovy source
131158
gpp.generateGsp(gsptarget)

grails-gsp/src/main/groovy/org/grails/gsp/compiler/GroovyPageParser.java

Lines changed: 61 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,11 @@
1515
*/
1616
package org.grails.gsp.compiler;
1717

18-
import grails.config.Config;
19-
import grails.config.Settings;
18+
import grails.config.ConfigMap;
2019
import grails.io.IOUtils;
2120
import grails.plugins.GrailsPluginInfo;
2221
import grails.util.Environment;
2322
import grails.util.GrailsStringUtils;
24-
import grails.util.Holders;
2523
import org.apache.commons.logging.Log;
2624
import org.apache.commons.logging.LogFactory;
2725
import org.grails.buffer.FastStringWriter;
@@ -150,10 +148,10 @@ public class GroovyPageParser implements Tokens {
150148
private long lastModified;
151149
private boolean precompileMode;
152150
private boolean sitemeshPreprocessMode=false;
153-
private String expressionCodecDirectiveValue;
154-
private String outCodecDirectiveValue;
155-
private String staticCodecDirectiveValue;
156-
private String taglibCodecDirectiveValue;
151+
private String expressionCodecDirectiveValue = OutputEncodingSettings.getDefaultValue(OutputEncodingSettings.EXPRESSION_CODEC_NAME);
152+
private String outCodecDirectiveValue = OutputEncodingSettings.getDefaultValue(OutputEncodingSettings.OUT_CODEC_NAME);
153+
private String staticCodecDirectiveValue = OutputEncodingSettings.getDefaultValue(OutputEncodingSettings.STATIC_CODEC_NAME);
154+
private String taglibCodecDirectiveValue = OutputEncodingSettings.getDefaultValue(OutputEncodingSettings.TAGLIB_CODEC_NAME) ;
157155

158156
private boolean enableSitemeshPreprocessing = true;
159157
private File keepGeneratedDirectory;
@@ -205,30 +203,12 @@ public GroovyPageParser(String name, String uri, String filename, String gspSour
205203
}
206204

207205
public GroovyPageParser(String name, String uri, String filename, String gspSource, String expressionCodecName) throws IOException {
208-
Config config = Holders.getConfig();
209-
if (config != null) {
210-
setEnableSitemeshPreprocessing(config.getProperty(GroovyPageParser.CONFIG_PROPERTY_GSP_SITEMESH_PREPROCESS, Boolean.class, enableSitemeshPreprocessing));
211-
}
212-
213-
GrailsPluginInfo pluginInfo = null;
214-
// TODO: figure out a way to restore plugin metadata for GSP
215-
// if (filename != null && BuildSettingsHolder.getSettings() != null) {
216-
// pluginInfo = GrailsPluginUtils.getPluginBuildSettings().getPluginInfoForSource(filename);
217-
// if (pluginInfo != null) {
218-
// pluginAnnotation = "@GrailsPlugin(name='" + pluginInfo.getName() + "', version='" +
219-
// pluginInfo.getVersion() + "')";
220-
// }
221-
// }
222206

223-
OutputEncodingSettings gspConfig = new OutputEncodingSettings(config);
224207

225208
this.expressionCodecDirectiveValue = expressionCodecName;
226-
if (expressionCodecDirectiveValue==null) {
227-
expressionCodecDirectiveValue = gspConfig.getCodecSettings(pluginInfo, OutputEncodingSettings.EXPRESSION_CODEC_NAME);
209+
if (expressionCodecDirectiveValue == null) {
210+
expressionCodecDirectiveValue = OutputEncodingSettings.getDefaultValue(OutputEncodingSettings.EXPRESSION_CODEC_NAME);
228211
}
229-
staticCodecDirectiveValue = gspConfig.getCodecSettings(pluginInfo, OutputEncodingSettings.STATIC_CODEC_NAME);
230-
outCodecDirectiveValue = gspConfig.getCodecSettings(pluginInfo, OutputEncodingSettings.OUT_CODEC_NAME);
231-
taglibCodecDirectiveValue = gspConfig.getCodecSettings(pluginInfo, OutputEncodingSettings.TAGLIB_CODEC_NAME);
232212

233213
Map<String, String> directives = parseDirectives(gspSource);
234214

@@ -247,10 +227,49 @@ public GroovyPageParser(String name, String uri, String filename, String gspSour
247227
makeSourceName(filename);
248228
}
249229

230+
231+
250232
public GroovyPageParser(String name, String uri, String filename, InputStream in) throws IOException {
251233
this(name, uri, filename, in, null, null);
252234
}
253235

236+
/**
237+
* Configures the parser for the given Config map
238+
*
239+
* @param config The config map
240+
*/
241+
public void configure(ConfigMap config) {
242+
setEnableSitemeshPreprocessing(
243+
config.getProperty(GroovyPageParser.CONFIG_PROPERTY_GSP_SITEMESH_PREPROCESS, Boolean.class, true)
244+
);
245+
246+
setExpressionCodecDirectiveValue(
247+
config.getProperty(OutputEncodingSettings.CONFIG_PROPERTY_GSP_CODECS + '.' + OutputEncodingSettings.EXPRESSION_CODEC_NAME, String.class,
248+
config.getProperty( OutputEncodingSettings.CONFIG_PROPERTY_DEFAULT_CODEC, String.class, OutputEncodingSettings.getDefaultValue(OutputEncodingSettings.EXPRESSION_CODEC_NAME) ))
249+
);
250+
251+
setStaticCodecDirectiveValue(
252+
config.getProperty(OutputEncodingSettings.CONFIG_PROPERTY_GSP_CODECS + '.' + OutputEncodingSettings.STATIC_CODEC_NAME, String.class, OutputEncodingSettings.getDefaultValue(OutputEncodingSettings.STATIC_CODEC_NAME ))
253+
);
254+
255+
setTaglibCodecDirectiveValue(
256+
config.getProperty(OutputEncodingSettings.CONFIG_PROPERTY_GSP_CODECS + '.' + OutputEncodingSettings.TAGLIB_CODEC_NAME, String.class, OutputEncodingSettings.getDefaultValue(OutputEncodingSettings.TAGLIB_CODEC_NAME ))
257+
);
258+
259+
setOutCodecDirectiveValue(
260+
config.getProperty(OutputEncodingSettings.CONFIG_PROPERTY_GSP_CODECS + '.' + OutputEncodingSettings.OUT_CODEC_NAME, String.class, OutputEncodingSettings.getDefaultValue(OutputEncodingSettings.OUT_CODEC_NAME ))
261+
);
262+
263+
Object keepDirObj = config.getProperty(GroovyPageParser.CONFIG_PROPERTY_GSP_KEEPGENERATED_DIR, Object.class);
264+
if (keepDirObj instanceof File) {
265+
setKeepGeneratedDirectory((File) keepDirObj);
266+
}
267+
else if (keepDirObj != null) {
268+
setKeepGeneratedDirectory(new File(String.valueOf(keepDirObj)));
269+
}
270+
271+
}
272+
254273
private Map<String, String> parseDirectives(String gspSource) {
255274
Map <String, String> result=new HashMap<String, String>();
256275
// strip gsp comments
@@ -1237,16 +1256,12 @@ private void pageImport(String value) {
12371256

12381257
private static String readStream(InputStream in, String gspEncoding) throws IOException {
12391258
if (gspEncoding == null) {
1240-
gspEncoding = getGspEncoding();
1259+
gspEncoding = DEFAULT_ENCODING;
12411260
}
12421261
return IOUtils.toString(in, gspEncoding);
12431262
}
12441263

12451264
public static String getGspEncoding(){
1246-
Config config = Holders.getConfig();
1247-
if(config != null) {
1248-
return config.getProperty(Settings.GSP_VIEW_ENCODING, DEFAULT_ENCODING);
1249-
}
12501265
return DEFAULT_ENCODING;
12511266
}
12521267

@@ -1368,4 +1383,18 @@ public String getTaglibCodecDirectiveValue() {
13681383
public void setTaglibCodecDirectiveValue(String taglibCodecDirectiveValue) {
13691384
this.taglibCodecDirectiveValue = taglibCodecDirectiveValue;
13701385
}
1386+
1387+
public void setExpressionCodecDirectiveValue(String expressionCodecDirectiveValue) {
1388+
this.expressionCodecDirectiveValue = expressionCodecDirectiveValue;
1389+
}
1390+
1391+
public void setOutCodecDirectiveValue(String outCodecDirectiveValue) {
1392+
this.outCodecDirectiveValue = outCodecDirectiveValue;
1393+
}
1394+
1395+
public void setStaticCodecDirectiveValue(String staticCodecDirectiveValue) {
1396+
this.staticCodecDirectiveValue = staticCodecDirectiveValue;
1397+
}
1398+
1399+
13711400
}

0 commit comments

Comments
 (0)