• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2010 Google Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.google.clearsilver.jsilver;
18 
19 import com.google.clearsilver.jsilver.autoescape.EscapeMode;
20 import com.google.clearsilver.jsilver.data.NoOpStringInternStrategy;
21 import com.google.clearsilver.jsilver.data.StringInternStrategy;
22 
23 import java.util.Map;
24 
25 /**
26  * Options for JSilver.
27  *
28  * Note: Setter methods also return reference to this, allowing options to be defined in one
29  * statement.
30  *
31  * e.g. new JSilver(..., new JSilverOptions().setSomething(true).setAnother(false));
32  *
33  * @see JSilver
34  */
35 public class JSilverOptions implements Cloneable {
36 
37   private boolean cacheTemplates = true;
38   private boolean compileTemplates = false;
39   private int initialBufferSize = 8192;
40   private boolean ignoreAttributes = false;
41   private Map<Object, String> precompiledTemplateMap = null;
42   private boolean useStrongCacheReferences = false;
43   private EscapeMode escapeMode = EscapeMode.ESCAPE_NONE;
44   private boolean propagateEscapeStatus = false;
45 
46   /**
47    * A pool of strings used to optimize HDF parsing.
48    *
49    * String interning has been shown to improve GC performance, but also to increase CPU usage. To
50    * avoid any possible unexpected changes in behavior it is disabled by default.
51    */
52   private StringInternStrategy stringInternStrategy = new NoOpStringInternStrategy();
53 
54   /**
55    * This flag is used to enable logging of all variables whose values are modified by auto escaping
56    * or &lt;cs escape&gt; commands. These will be logged at {@code Level.WARNING}.
57    */
58   private boolean logEscapedVariables = false;
59   private boolean useOutputBufferPool = false;
60   private boolean stripHtmlWhiteSpace = false;
61   private boolean stripStructuralWhiteSpace = false;
62   private boolean allowGlobalDataModification = false;
63   private boolean keepTemplateCacheFresh = false;
64   private int loadPathCacheSize = 1000;
65 
66   // When adding fields, ensure you:
67   // * add getter.
68   // * add setter (which returns this).
69   // * add to clone() method if necessary.
70 
71   /**
72    * Set the initial size of the load path cache container. Setting this to 0 causes load path cache
73    * to be disabled.
74    */
setLoadPathCacheSize(int loadPathCacheSize)75   public JSilverOptions setLoadPathCacheSize(int loadPathCacheSize) {
76     this.loadPathCacheSize = loadPathCacheSize;
77     return this;
78   }
79 
80   /**
81    * @see #setLoadPathCacheSize(int)
82    */
getLoadPathCacheSize()83   public int getLoadPathCacheSize() {
84     return loadPathCacheSize;
85   }
86 
87   /**
88    * Whether to cache templates. This will only ever load and parse a template from disk once. Best
89    * switched on for production but left off for production (so you can update templates without
90    * restarting).
91    */
setCacheTemplates(boolean cacheTemplates)92   public JSilverOptions setCacheTemplates(boolean cacheTemplates) {
93     this.cacheTemplates = cacheTemplates;
94     return this;
95   }
96 
97   /**
98    * @see #setCacheTemplates(boolean)
99    */
getCacheTemplates()100   public boolean getCacheTemplates() {
101     return cacheTemplates;
102   }
103 
104   /**
105    * Compile templates to Java byte code. This slows down the initial render as it performs a
106    * compilation step, but then subsequent render are faster.
107    *
108    * Compiled templates are always cached.
109    *
110    * WARNING: This functionality is experimental. Use with caution.
111    */
setCompileTemplates(boolean compileTemplates)112   public JSilverOptions setCompileTemplates(boolean compileTemplates) {
113     this.compileTemplates = compileTemplates;
114     return this;
115   }
116 
117   /**
118    * @see #setCompileTemplates(boolean)
119    */
getCompileTemplates()120   public boolean getCompileTemplates() {
121     return compileTemplates;
122   }
123 
124   /**
125    * If set, then HDF attributes in HDF files will be ignored and not stored in the Data object
126    * filled by the parser. Default is {@code false}. Many applications use HDF attributes only in
127    * template preprocessing (like translation support) and never in production servers where the
128    * templates are rendered. By disabling attribute parsing, these applications can save on memory
129    * for storing HDF structures read from files.
130    */
setIgnoreAttributes(boolean ignoreAttributes)131   public JSilverOptions setIgnoreAttributes(boolean ignoreAttributes) {
132     this.ignoreAttributes = ignoreAttributes;
133     return this;
134   }
135 
136   /**
137    * @see #setIgnoreAttributes(boolean)
138    */
getIgnoreAttributes()139   public boolean getIgnoreAttributes() {
140     return ignoreAttributes;
141   }
142 
143   /**
144    * Initial buffer size used when rendering directly to a string.
145    */
setInitialBufferSize(int initialBufferSize)146   public JSilverOptions setInitialBufferSize(int initialBufferSize) {
147     this.initialBufferSize = initialBufferSize;
148     return this;
149   }
150 
151   /**
152    * @see #setInitialBufferSize(int)
153    */
getInitialBufferSize()154   public int getInitialBufferSize() {
155     return initialBufferSize;
156   }
157 
158   /**
159    * Optional mapping of TemplateLoader keys to Template instances that will be queried when loading
160    * a template. If the Template is found it is returned. If not, the next template loader is
161    * consulted.
162    *
163    * @param precompiledTemplateMap map of TemplateLoader keys to corresponding class names that
164    *        should be valid BaseCompiledTemplate subclasses. Set to {@code null} (default) to not
165    *        load precompiled templates.
166    */
setPrecompiledTemplateMap(Map<Object, String> precompiledTemplateMap)167   public JSilverOptions setPrecompiledTemplateMap(Map<Object, String> precompiledTemplateMap) {
168     this.precompiledTemplateMap = precompiledTemplateMap;
169     return this;
170   }
171 
172   /**
173    * @see #setPrecompiledTemplateMap(java.util.Map)
174    * @return a mapping of TemplateLoader keys to corresponding BaseCompiledTemplate class names, or
175    *         {@code null} (default) if no precompiled templates should be preloaded.
176    */
getPrecompiledTemplateMap()177   public Map<Object, String> getPrecompiledTemplateMap() {
178     return precompiledTemplateMap;
179   }
180 
181   /**
182    * If {@code true}, then the template cache will use strong persistent references for the values.
183    * If {@code false} (default) it will use soft references. Warning: The cache size is unbounded so
184    * only use this option if you have sufficient memory to load all the Templates into memory.
185    */
setUseStrongCacheReferences(boolean value)186   public JSilverOptions setUseStrongCacheReferences(boolean value) {
187     this.useStrongCacheReferences = value;
188     return this;
189   }
190 
191   /**
192    * @see #setUseStrongCacheReferences(boolean)
193    */
getUseStrongCacheReferences()194   public boolean getUseStrongCacheReferences() {
195     return useStrongCacheReferences;
196   }
197 
198   /**
199    * @see #setEscapeMode(com.google.clearsilver.jsilver.autoescape.EscapeMode)
200    */
getEscapeMode()201   public EscapeMode getEscapeMode() {
202     return escapeMode;
203   }
204 
205   /**
206    * Escape any template being rendered with the given escaping mode. If the mode is ESCAPE_HTML,
207    * ESCAPE_URL or ESCAPE_JS, the corresponding escaping will be all variables in the template. If
208    * the mode is ESCAPE_AUTO, enable <a href="http://go/autoescapecs">auto escaping</a> on
209    * templates. For each variable in the template, this will determine what type of escaping should
210    * be applied to the variable, and automatically apply this escaping. This flag can be overriden
211    * by setting appropriate HDF variables before loading a template. If Config.AutoEscape is 1, auto
212    * escaping is enabled. If Config.VarEscapeMode is set to one of 'html', 'js' or 'url', the
213    * corresponding escaping is applied to all variables.
214    *
215    * @param escapeMode
216    */
setEscapeMode(EscapeMode escapeMode)217   public JSilverOptions setEscapeMode(EscapeMode escapeMode) {
218     this.escapeMode = escapeMode;
219     return this;
220   }
221 
222   /**
223    * @see #setPropagateEscapeStatus
224    */
getPropagateEscapeStatus()225   public boolean getPropagateEscapeStatus() {
226     return propagateEscapeStatus;
227   }
228 
229   /**
230    * Only used for templates that are being <a href="http://go/autoescapecs">auto escaped</a>. If
231    * {@code true} and auto escaping is enabled, variables created by &lt;cs set&gt; or &lt;cs
232    * call&gt; commands are not auto escaped if they are assigned constant or escaped values. This is
233    * disabled by default.
234    *
235    * @see #setEscapeMode
236    */
setPropagateEscapeStatus(boolean propagateEscapeStatus)237   public JSilverOptions setPropagateEscapeStatus(boolean propagateEscapeStatus) {
238     this.propagateEscapeStatus = propagateEscapeStatus;
239     return this;
240   }
241 
242   /**
243    * Sets the {@link StringInternStrategy} object that will be used to optimize HDF parsing.
244    *
245    * <p>
246    * Set value should not be {@code null} as it can cause {@link NullPointerException}.
247    *
248    * @param stringInternStrategy - {@link StringInternStrategy} object
249    */
setStringInternStrategy(StringInternStrategy stringInternStrategy)250   public void setStringInternStrategy(StringInternStrategy stringInternStrategy) {
251     if (stringInternStrategy == null) {
252       throw new IllegalArgumentException("StringInternStrategy should not be null.");
253     }
254     this.stringInternStrategy = stringInternStrategy;
255   }
256 
257   /**
258    * Returns {@link StringInternStrategy} object that is used for optimization of HDF parsing.
259    *
260    * <p>
261    * The returned value should never be {@code null}.
262    *
263    * @return currently used {@link StringInternStrategy} object.
264    */
getStringInternStrategy()265   public StringInternStrategy getStringInternStrategy() {
266     return stringInternStrategy;
267   }
268 
269   /**
270    * If {@code true}, then use a threadlocal buffer pool for holding rendered output when outputting
271    * to String. Assumes that render() is called from a thread and that thread will not reenter
272    * render() while it is running. If {@code false}, a new buffer is allocated for each request
273    * where an Appendable output object was not provided.
274    */
setUseOutputBufferPool(boolean value)275   public JSilverOptions setUseOutputBufferPool(boolean value) {
276     this.useOutputBufferPool = value;
277     return this;
278   }
279 
280   /**
281    * @see #setUseOutputBufferPool(boolean)
282    */
getUseOutputBufferPool()283   public boolean getUseOutputBufferPool() {
284     return useOutputBufferPool;
285   }
286 
287   /**
288    * If {@code true}, then unnecessary whitespace will be stripped from the output. 'Unnecessary' is
289    * meant in terms of HTML output. See
290    * {@link com.google.clearsilver.jsilver.template.HtmlWhiteSpaceStripper} for more info.
291    */
setStripHtmlWhiteSpace(boolean value)292   public JSilverOptions setStripHtmlWhiteSpace(boolean value) {
293     this.stripHtmlWhiteSpace = value;
294     return this;
295   }
296 
297   /**
298    * @see #setStripHtmlWhiteSpace(boolean)
299    */
getStripHtmlWhiteSpace()300   public boolean getStripHtmlWhiteSpace() {
301     return stripHtmlWhiteSpace;
302   }
303 
304   /**
305    * If {@code true}, then structural whitespace will be stripped from the output. This allows
306    * templates to be written to more closely match normal programming languages. See
307    * {@link com.google.clearsilver.jsilver.syntax.StructuralWhitespaceStripper} for more info.
308    */
setStripStructuralWhiteSpace(boolean value)309   public JSilverOptions setStripStructuralWhiteSpace(boolean value) {
310     this.stripStructuralWhiteSpace = value;
311     return this;
312   }
313 
314   /**
315    * @see #setStripHtmlWhiteSpace(boolean)
316    */
getStripStructuralWhiteSpace()317   public boolean getStripStructuralWhiteSpace() {
318     return stripStructuralWhiteSpace;
319   }
320 
321   /**
322    * Use this method to disable wrapping the global HDF with an UnmodifiableData object which
323    * prevents modification. This flag is here in case there are corner cases or performance reasons
324    * that someone may want to disable this protection.
325    *
326    * Should not be set to {@code true} unless incompatibilities or performance issues found. Note,
327    * that setting to {@code true} could introduce bugs in templates that acquire local references to
328    * the global data structure and then try to modify them, which is not the intended behavior.
329    * Allowing global data modification during rendering is not compatible with the recently fixed
330    * JNI Clearsilver library.
331    *
332    * TODO: Remove once legacy mode is no longer needed.
333    *
334    * @param allowGlobalDataModification {@code true} if you want to avoid wrapping the global HDF so
335    *        that all writes to it during rendering are prevented and throw an exception.
336    * @return this object.
337    */
setAllowGlobalDataModification(boolean allowGlobalDataModification)338   public JSilverOptions setAllowGlobalDataModification(boolean allowGlobalDataModification) {
339     this.allowGlobalDataModification = allowGlobalDataModification;
340     return this;
341   }
342 
343   /**
344    * @see #setAllowGlobalDataModification(boolean)
345    */
getAllowGlobalDataModification()346   public boolean getAllowGlobalDataModification() {
347     return allowGlobalDataModification;
348   }
349 
350   /**
351    * @param keepTemplateCacheFresh {@code true} to have the template cache call
352    *        {@link com.google.clearsilver.jsilver.resourceloader.ResourceLoader#getResourceVersionId(String)}
353    *        to check if it should refresh its cache entries (this incurs a small performance penalty
354    *        each time the cache is accessed)
355    * @return this object
356    */
setKeepTemplateCacheFresh(boolean keepTemplateCacheFresh)357   public JSilverOptions setKeepTemplateCacheFresh(boolean keepTemplateCacheFresh) {
358     this.keepTemplateCacheFresh = keepTemplateCacheFresh;
359     return this;
360   }
361 
362   /**
363    * @see #setKeepTemplateCacheFresh(boolean)
364    */
getKeepTemplateCacheFresh()365   public boolean getKeepTemplateCacheFresh() {
366     return keepTemplateCacheFresh;
367   }
368 
369   @Override
clone()370   public JSilverOptions clone() {
371     try {
372       return (JSilverOptions) super.clone();
373     } catch (CloneNotSupportedException impossible) {
374       throw new AssertionError(impossible);
375     }
376   }
377 
378   /**
379    * @see #setLogEscapedVariables
380    */
getLogEscapedVariables()381   public boolean getLogEscapedVariables() {
382     return logEscapedVariables;
383   }
384 
385   /**
386    * Use this method to enable logging of all variables whose values are modified by auto escaping
387    * or &lt;cs escape&gt; commands. These will be logged at {@code Level.WARNING}. This is useful
388    * for detecting variables that should be exempt from auto escaping.
389    *
390    * <p>
391    * It is recommended to only enable this flag during testing or debugging and not for production
392    * jobs.
393    *
394    * @see #setEscapeMode
395    */
setLogEscapedVariables(boolean logEscapedVariables)396   public JSilverOptions setLogEscapedVariables(boolean logEscapedVariables) {
397     this.logEscapedVariables = logEscapedVariables;
398     return this;
399   }
400 }
401