Source Code Cross Referenced for Configuration.java in  » Template-Engine » freemarker-2.3.10 » freemarker » template » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Template Engine » freemarker 2.3.10 » freemarker.template 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Copyright (c) 2003-2006 The Visigoth Software Society. All rights
003:         * reserved.
004:         *
005:         * Redistribution and use in source and binary forms, with or without
006:         * modification, are permitted provided that the following conditions
007:         * are met:
008:         *
009:         * 1. Redistributions of source code must retain the above copyright
010:         *    notice, this list of conditions and the following disclaimer.
011:         *
012:         * 2. Redistributions in binary form must reproduce the above copyright
013:         *    notice, this list of conditions and the following disclaimer in
014:         *    the documentation and/or other materials provided with the
015:         *    distribution.
016:         *
017:         * 3. The end-user documentation included with the redistribution, if
018:         *    any, must include the following acknowledgement:
019:         *       "This product includes software developed by the
020:         *        Visigoth Software Society (http://www.visigoths.org/)."
021:         *    Alternately, this acknowledgement may appear in the software itself,
022:         *    if and wherever such third-party acknowledgements normally appear.
023:         *
024:         * 4. Neither the name "FreeMarker", "Visigoth", nor any of the names of the 
025:         *    project contributors may be used to endorse or promote products derived
026:         *    from this software without prior written permission. For written
027:         *    permission, please contact visigoths@visigoths.org.
028:         *
029:         * 5. Products derived from this software may not be called "FreeMarker" or "Visigoth"
030:         *    nor may "FreeMarker" or "Visigoth" appear in their names
031:         *    without prior written permission of the Visigoth Software Society.
032:         *
033:         * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
034:         * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
035:         * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
036:         * DISCLAIMED.  IN NO EVENT SHALL THE VISIGOTH SOFTWARE SOCIETY OR
037:         * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
038:         * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
039:         * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
040:         * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
041:         * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
042:         * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
043:         * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
044:         * SUCH DAMAGE.
045:         * ====================================================================
046:         *
047:         * This software consists of voluntary contributions made by many
048:         * individuals on behalf of the Visigoth Software Society. For more
049:         * information on the Visigoth Software Society, please see
050:         * http://www.visigoths.org/
051:         */
052:
053:        package freemarker.template;
054:
055:        import java.io.*;
056:        import java.util.*;
057:
058:        import freemarker.cache.*;
059:        import freemarker.core.*;
060:        import freemarker.template.utility.*;
061:
062:        /**
063:         * Main entry point into the FreeMarker API, this class encapsulates the 
064:         * various configuration parameters with which FreeMarker is run, as well
065:         * as serves as a central template loading and caching point. Note that
066:         * this class uses a default strategy for loading 
067:         * and caching templates. You can plug in a replacement
068:         * template loading mechanism by using the {@link #setTemplateLoader(TemplateLoader)}
069:         * method.
070:         *
071:         * This object is <em>not synchronized</em>. Thus, the settings must not be changed
072:         * after you have started to access the object from multiple threads. If you use multiple
073:         * threads, set everything directly after you have instantiated the <code>Configuration</code>
074:         * object, and don't change the settings anymore.
075:         *
076:         * @author <a href="mailto:jon@revusky.com">Jonathan Revusky</a>
077:         * @author Attila Szegedi
078:         * @version $Id: Configuration.java,v 1.122.2.5 2006/04/26 21:25:19 ddekany Exp $
079:         */
080:
081:        public class Configuration extends Configurable implements  Cloneable {
082:            public static final String DEFAULT_ENCODING_KEY = "default_encoding";
083:            public static final String LOCALIZED_LOOKUP_KEY = "localized_lookup";
084:            public static final String STRICT_SYNTAX_KEY = "strict_syntax";
085:            public static final String WHITESPACE_STRIPPING_KEY = "whitespace_stripping";
086:            public static final String CACHE_STORAGE_KEY = "cache_storage";
087:            public static final String TEMPLATE_UPDATE_DELAY_KEY = "template_update_delay";
088:            public static final String AUTO_IMPORT_KEY = "auto_import";
089:            public static final String AUTO_INCLUDE_KEY = "auto_include";
090:            public static final String TAG_SYNTAX_KEY = "tag_syntax";
091:            public static final int AUTO_DETECT_TAG_SYNTAX = 0;
092:            public static final int ANGLE_BRACKET_TAG_SYNTAX = 1;
093:            public static final int SQUARE_BRACKET_TAG_SYNTAX = 2;
094:
095:            private static Configuration defaultConfig = new Configuration();
096:            private static String cachedVersion;
097:            private boolean strictSyntax = true, localizedLookup = true,
098:                    whitespaceStripping = true;
099:            private int tagSyntax = ANGLE_BRACKET_TAG_SYNTAX;
100:
101:            private TemplateCache cache;
102:            private HashMap variables = new HashMap();
103:            private HashMap encodingMap = new HashMap();
104:            private Map autoImportMap = new HashMap();
105:            private ArrayList autoImports = new ArrayList(),
106:                    autoIncludes = new ArrayList();
107:            private String defaultEncoding = SecurityUtilities
108:                    .getSystemProperty("file.encoding");
109:
110:            public Configuration() {
111:                cache = new TemplateCache();
112:                cache.setConfiguration(this );
113:                cache.setDelay(5000);
114:                loadBuiltInSharedVariables();
115:            }
116:
117:            public Object clone() {
118:                try {
119:                    Configuration copy = (Configuration) super .clone();
120:                    copy.variables = new HashMap(variables);
121:                    copy.encodingMap = new HashMap(encodingMap);
122:                    copy.createTemplateCache(cache.getTemplateLoader(), cache
123:                            .getCacheStorage());
124:                    return copy;
125:                } catch (CloneNotSupportedException e) {
126:                    throw new RuntimeException(
127:                            "Clone is not supported, but it should be: "
128:                                    + e.getMessage());
129:                }
130:            }
131:
132:            private void loadBuiltInSharedVariables() {
133:                variables.put("capture_output", new CaptureOutput());
134:                variables.put("compress", StandardCompress.INSTANCE);
135:                variables.put("html_escape", new HtmlEscape());
136:                variables.put("normalize_newlines", new NormalizeNewlines());
137:                variables.put("xml_escape", new XmlEscape());
138:            }
139:
140:            /**
141:             * Loads a preset language-to-encoding map. It assumes the usual character
142:             * encodings for most languages.
143:             * The previous content of the encoding map will be lost.
144:             * This default map currently contains the following mappings:
145:             * <table>
146:             *   <tr><td>ar</td><td>ISO-8859-6</td></tr>
147:             *   <tr><td>be</td><td>ISO-8859-5</td></tr>
148:             *   <tr><td>bg</td><td>ISO-8859-5</td></tr>
149:             *   <tr><td>ca</td><td>ISO-8859-1</td></tr>
150:             *   <tr><td>cs</td><td>ISO-8859-2</td></tr>
151:             *   <tr><td>da</td><td>ISO-8859-1</td></tr>
152:             *   <tr><td>de</td><td>ISO-8859-1</td></tr>
153:             *   <tr><td>el</td><td>ISO-8859-7</td></tr>
154:             *   <tr><td>en</td><td>ISO-8859-1</td></tr>
155:             *   <tr><td>es</td><td>ISO-8859-1</td></tr>
156:             *   <tr><td>et</td><td>ISO-8859-1</td></tr>
157:             *   <tr><td>fi</td><td>ISO-8859-1</td></tr>
158:             *   <tr><td>fr</td><td>ISO-8859-1</td></tr>
159:             *   <tr><td>hr</td><td>ISO-8859-2</td></tr>
160:             *   <tr><td>hu</td><td>ISO-8859-2</td></tr>
161:             *   <tr><td>is</td><td>ISO-8859-1</td></tr>
162:             *   <tr><td>it</td><td>ISO-8859-1</td></tr>
163:             *   <tr><td>iw</td><td>ISO-8859-8</td></tr>
164:             *   <tr><td>ja</td><td>Shift_JIS</td></tr>
165:             *   <tr><td>ko</td><td>EUC-KR</td></tr>    
166:             *   <tr><td>lt</td><td>ISO-8859-2</td></tr>
167:             *   <tr><td>lv</td><td>ISO-8859-2</td></tr>
168:             *   <tr><td>mk</td><td>ISO-8859-5</td></tr>
169:             *   <tr><td>nl</td><td>ISO-8859-1</td></tr>
170:             *   <tr><td>no</td><td>ISO-8859-1</td></tr>
171:             *   <tr><td>pl</td><td>ISO-8859-2</td></tr>
172:             *   <tr><td>pt</td><td>ISO-8859-1</td></tr>
173:             *   <tr><td>ro</td><td>ISO-8859-2</td></tr>
174:             *   <tr><td>ru</td><td>ISO-8859-5</td></tr>
175:             *   <tr><td>sh</td><td>ISO-8859-5</td></tr>
176:             *   <tr><td>sk</td><td>ISO-8859-2</td></tr>
177:             *   <tr><td>sl</td><td>ISO-8859-2</td></tr>
178:             *   <tr><td>sq</td><td>ISO-8859-2</td></tr>
179:             *   <tr><td>sr</td><td>ISO-8859-5</td></tr>
180:             *   <tr><td>sv</td><td>ISO-8859-1</td></tr>
181:             *   <tr><td>tr</td><td>ISO-8859-9</td></tr>
182:             *   <tr><td>uk</td><td>ISO-8859-5</td></tr>
183:             *   <tr><td>zh</td><td>GB2312</td></tr>
184:             *   <tr><td>zh_TW</td><td>Big5</td></tr>
185:             * </table>
186:             * @see #clearEncodingMap
187:             * @see #setEncoding
188:             */
189:            public void loadBuiltInEncodingMap() {
190:                encodingMap.clear();
191:                encodingMap.put("ar", "ISO-8859-6");
192:                encodingMap.put("be", "ISO-8859-5");
193:                encodingMap.put("bg", "ISO-8859-5");
194:                encodingMap.put("ca", "ISO-8859-1");
195:                encodingMap.put("cs", "ISO-8859-2");
196:                encodingMap.put("da", "ISO-8859-1");
197:                encodingMap.put("de", "ISO-8859-1");
198:                encodingMap.put("el", "ISO-8859-7");
199:                encodingMap.put("en", "ISO-8859-1");
200:                encodingMap.put("es", "ISO-8859-1");
201:                encodingMap.put("et", "ISO-8859-1");
202:                encodingMap.put("fi", "ISO-8859-1");
203:                encodingMap.put("fr", "ISO-8859-1");
204:                encodingMap.put("hr", "ISO-8859-2");
205:                encodingMap.put("hu", "ISO-8859-2");
206:                encodingMap.put("is", "ISO-8859-1");
207:                encodingMap.put("it", "ISO-8859-1");
208:                encodingMap.put("iw", "ISO-8859-8");
209:                encodingMap.put("ja", "Shift_JIS");
210:                encodingMap.put("ko", "EUC-KR");
211:                encodingMap.put("lt", "ISO-8859-2");
212:                encodingMap.put("lv", "ISO-8859-2");
213:                encodingMap.put("mk", "ISO-8859-5");
214:                encodingMap.put("nl", "ISO-8859-1");
215:                encodingMap.put("no", "ISO-8859-1");
216:                encodingMap.put("pl", "ISO-8859-2");
217:                encodingMap.put("pt", "ISO-8859-1");
218:                encodingMap.put("ro", "ISO-8859-2");
219:                encodingMap.put("ru", "ISO-8859-5");
220:                encodingMap.put("sh", "ISO-8859-5");
221:                encodingMap.put("sk", "ISO-8859-2");
222:                encodingMap.put("sl", "ISO-8859-2");
223:                encodingMap.put("sq", "ISO-8859-2");
224:                encodingMap.put("sr", "ISO-8859-5");
225:                encodingMap.put("sv", "ISO-8859-1");
226:                encodingMap.put("tr", "ISO-8859-9");
227:                encodingMap.put("uk", "ISO-8859-5");
228:                encodingMap.put("zh", "GB2312");
229:                encodingMap.put("zh_TW", "Big5");
230:            }
231:
232:            /**
233:             * Clears language-to-encoding map.
234:             * @see #loadBuiltInEncodingMap
235:             * @see #setEncoding
236:             */
237:            public void clearEncodingMap() {
238:                encodingMap.clear();
239:            }
240:
241:            /**
242:             * Returns the default (singleton) Configuration object. Note that you can
243:             * create as many separate configurations as you wish; this global instance
244:             * is provided for convenience, or when you have no reason to use a separate
245:             * instance.
246:             * 
247:             * @deprecated The usage of the static singleton (the "default")
248:             * {@link Configuration} instance can easily cause erroneous, unpredictable
249:             * behavior. This is because multiple independent software components may use
250:             * FreeMarker internally inside the same application, so they will interfere
251:             * because of the common {@link Configuration} instance. Each such component
252:             * should use its own private {@link Configuration} object instead, that it
253:             * typically creates with <code>new Configuration()</code> when the component
254:             * is initialized.
255:             */
256:            static public Configuration getDefaultConfiguration() {
257:                return defaultConfig;
258:            }
259:
260:            /**
261:             * Sets the Configuration object that will be retrieved from future calls
262:             * to {@link #getDefaultConfiguration()}.
263:             * 
264:             * @deprecated Using the "default" {@link Configuration} instance can
265:             * easily lead to erroneous, unpredictable behaviour.
266:             * See more {@link Configuration#getDefaultConfiguration() here...}.
267:             */
268:            static public void setDefaultConfiguration(Configuration config) {
269:                defaultConfig = config;
270:            }
271:
272:            /**
273:             * Sets a template loader that is used to look up and load templates.
274:             * By providing your own template loader, you can customize the way
275:             * templates are loaded. Several convenience methods in this class already
276:             * allow you to install commonly used loaders:
277:             * {@link #setClassForTemplateLoading(Class, String)}, 
278:             * {@link #setDirectoryForTemplateLoading(File)}, and
279:             * {@link #setServletContextForTemplateLoading(Object, String)}. By default,
280:             * a multi-loader is used that first tries to load a template from the file
281:             * in the current directory, then from a resource on the classpath.
282:             */
283:            public synchronized void setTemplateLoader(TemplateLoader loader) {
284:                createTemplateCache(loader, cache.getCacheStorage());
285:            }
286:
287:            private void createTemplateCache(TemplateLoader loader,
288:                    CacheStorage storage) {
289:                TemplateCache oldCache = cache;
290:                cache = new TemplateCache(loader, storage);
291:                cache.setDelay(oldCache.getDelay());
292:                cache.setConfiguration(this );
293:                cache.setLocalizedLookup(localizedLookup);
294:            }
295:
296:            /**
297:             * @return the template loader that is used to look up and load templates.
298:             * @see #setTemplateLoader
299:             */
300:            public TemplateLoader getTemplateLoader() {
301:                return cache.getTemplateLoader();
302:            }
303:
304:            public synchronized void setCacheStorage(CacheStorage storage) {
305:                createTemplateCache(cache.getTemplateLoader(), storage);
306:            }
307:
308:            /**
309:             * Set the explicit directory from which to load templates.
310:             */
311:            public void setDirectoryForTemplateLoading(File dir)
312:                    throws IOException {
313:                TemplateLoader tl = getTemplateLoader();
314:                if (tl instanceof  FileTemplateLoader) {
315:                    String path = ((FileTemplateLoader) tl).baseDir
316:                            .getCanonicalPath();
317:                    if (path.equals(dir.getCanonicalPath()))
318:                        return;
319:                }
320:                setTemplateLoader(new FileTemplateLoader(dir));
321:            }
322:
323:            /**
324:             * Sets the servlet context from which to load templates
325:             * @param sctxt the ServletContext object. Note that the type is <code>Object</code>
326:             *        to prevent class loading errors when user who uses FreeMarker not for
327:             *        servlets has no javax.servlet in the CLASSPATH.
328:             * @param path the path relative to the ServletContext.
329:             * If this path is absolute, it is taken to be relative
330:             * to the server's URL, i.e. http://myserver.com/
331:             * and if the path is relative, it is taken to be 
332:             * relative to the web app context, i.e.
333:             * http://myserver.context.com/mywebappcontext/
334:             */
335:            public void setServletContextForTemplateLoading(Object sctxt,
336:                    String path) {
337:                try {
338:                    if (path == null) {
339:                        setTemplateLoader((TemplateLoader) ClassUtil
340:                                .forName(
341:                                        "freemarker.cache.WebappTemplateLoader")
342:                                .getConstructor(
343:                                        new Class[] { ClassUtil
344:                                                .forName("javax.servlet.ServletContext") })
345:                                .newInstance(new Object[] { sctxt }));
346:                    } else {
347:                        setTemplateLoader((TemplateLoader) ClassUtil
348:                                .forName(
349:                                        "freemarker.cache.WebappTemplateLoader")
350:                                .getConstructor(
351:                                        new Class[] {
352:                                                ClassUtil
353:                                                        .forName("javax.servlet.ServletContext"),
354:                                                String.class }).newInstance(
355:                                        new Object[] { sctxt, path }));
356:                    }
357:                } catch (Exception exc) {
358:                    throw new RuntimeException("Internal FreeMarker error: "
359:                            + exc);
360:                }
361:            }
362:
363:            /**
364:             * Sets a class relative to which we do the 
365:             * Class.getResource() call to load templates.
366:             */
367:            public void setClassForTemplateLoading(Class clazz,
368:                    String pathPrefix) {
369:                setTemplateLoader(new ClassTemplateLoader(clazz, pathPrefix));
370:            }
371:
372:            /**
373:             * Set the time in seconds that must elapse before checking whether there is a newer
374:             * version of a template file.
375:             * This method is thread-safe and can be called while the engine works.
376:             */
377:            public void setTemplateUpdateDelay(int delay) {
378:                cache.setDelay(1000L * delay);
379:            }
380:
381:            /**
382:             * Sets whether directives such as if, else, etcetera
383:             * must be written as #if, #else, etcetera.
384:             * Any tag not starting with &lt;# or &lt;/# is considered as plain text
385:             * and will go to the output as is. Tag starting with &lt# or &lt/# must
386:             * be valid FTL tag, or else the template is invalid (i.e. &lt;#noSuchDirective>
387:             * is an error).
388:             */
389:
390:            public void setStrictSyntaxMode(boolean b) {
391:                strictSyntax = b;
392:            }
393:
394:            /**
395:             * Tells whether directives such as if, else, etcetera
396:             * must be written as #if, #else, etcetera.
397:             *
398:             * @see #setStrictSyntaxMode
399:             */
400:            public boolean getStrictSyntaxMode() {
401:                return strictSyntax;
402:            }
403:
404:            /**
405:             * Sets whether the FTL parser will try to remove
406:             * superfluous white-space around certain FTL tags.
407:             */
408:            public void setWhitespaceStripping(boolean b) {
409:                whitespaceStripping = b;
410:            }
411:
412:            /**
413:             * Gets whether the FTL parser will try to remove
414:             * superfluous white-space around certain FTL tags.
415:             *
416:             * @see #setWhitespaceStripping
417:             */
418:            public boolean getWhitespaceStripping() {
419:                return whitespaceStripping;
420:            }
421:
422:            /**
423:             * Determines the syntax of the template files (angle bracket VS square bracket)
424:             * that has no <markup>ftl</markup> directive in it. The <code>tagSyntax</code>
425:             * parameter must be one of:
426:             * <ul>
427:             *   <li>{@link Configuration#AUTO_DETECT_TAG_SYNTAX}:
428:             *     use the syntax of the first FreeMarker tag (can be anything, like <tt>list</tt>,
429:             *     <tt>include</tt>, user defined, ...etc)
430:             *   <li>{@link Configuration#ANGLE_BRACKET_TAG_SYNTAX}:
431:             *     use the angle bracket syntax (the normal syntax)
432:             *   <li>{@link Configuration#SQUARE_BRACKET_TAG_SYNTAX}:
433:             *     use the square bracket syntax
434:             * </ul>
435:             *
436:             * <p>In FreeMarker 2.3.x {@link Configuration#ANGLE_BRACKET_TAG_SYNTAX} is the
437:             * default for better backward compatibility. Starting from 2.4.x {@link
438:             * Configuration#AUTO_DETECT_TAG_SYNTAX} is the default, so it is recommended to use
439:             * that even for 2.3.x.
440:             * 
441:             * <p>This setting is ignored for the templates that have <tt>ftl</tt> directive in
442:             * it. For those templates the syntax used for the <tt>ftl</tt> directive determines
443:             * the syntax.
444:             */
445:            public void setTagSyntax(int tagSyntax) {
446:                if (tagSyntax != AUTO_DETECT_TAG_SYNTAX
447:                        && tagSyntax != SQUARE_BRACKET_TAG_SYNTAX
448:                        && tagSyntax != ANGLE_BRACKET_TAG_SYNTAX) {
449:                    throw new IllegalArgumentException(
450:                            "This can only be set to one of three settings: Configuration.AUTO_DETECT_TAG_SYNTAX, Configuration.ANGLE_BRACKET_SYNTAX, or Configuration.SQAUARE_BRACKET_SYNTAX");
451:                }
452:                this .tagSyntax = tagSyntax;
453:            }
454:
455:            /**
456:             * @return whether the alternative square bracket
457:             * syntax is set as the default
458:             */
459:            public int getTagSyntax() {
460:                return tagSyntax;
461:            }
462:
463:            /**
464:             * Equivalent to <tt>getTemplate(name, thisCfg.getLocale(), thisCfg.getEncoding(thisCfg.getLocale()), true)</tt>.
465:             */
466:            public Template getTemplate(String name) throws IOException {
467:                Locale loc = getLocale();
468:                return getTemplate(name, loc, getEncoding(loc), true);
469:            }
470:
471:            /**
472:             * Equivalent to <tt>getTemplate(name, locale, thisCfg.getEncoding(locale), true)</tt>.
473:             */
474:            public Template getTemplate(String name, Locale locale)
475:                    throws IOException {
476:                return getTemplate(name, locale, getEncoding(locale), true);
477:            }
478:
479:            /**
480:             * Equivalent to <tt>getTemplate(name, thisCfg.getLocale(), encoding, true)</tt>.
481:             */
482:            public Template getTemplate(String name, String encoding)
483:                    throws IOException {
484:                return getTemplate(name, getLocale(), encoding, true);
485:            }
486:
487:            /**
488:             * Equivalent to <tt>getTemplate(name, locale, encoding, true)</tt>.
489:             */
490:            public Template getTemplate(String name, Locale locale,
491:                    String encoding) throws IOException {
492:                return getTemplate(name, locale, encoding, true);
493:            }
494:
495:            /**
496:             * Retrieves a template specified by a name and locale, interpreted using
497:             * the specified character encoding, either parsed or unparsed. For the
498:             * exact semantics of parameters, see 
499:             * {@link TemplateCache#getTemplate(String, Locale, String, boolean)}.
500:             * @return the requested template.
501:             * @throws FileNotFoundException if the template could not be found.
502:             * @throws IOException if there was a problem loading the template.
503:             * @throws ParseException (extends <code>IOException</code>) if the template is syntactically bad.
504:             */
505:            public Template getTemplate(String name, Locale locale,
506:                    String encoding, boolean parse) throws IOException {
507:                Template result = cache.getTemplate(name, locale, encoding,
508:                        parse);
509:                if (result == null) {
510:                    throw new FileNotFoundException("Template " + name
511:                            + " not found.");
512:                }
513:                return result;
514:            }
515:
516:            /**
517:             * Sets the default encoding for converting bytes to characters when
518:             * reading template files in a locale for which no explicit encoding
519:             * was specified. Defaults to default system encoding.
520:             */
521:            public void setDefaultEncoding(String encoding) {
522:                defaultEncoding = encoding;
523:            }
524:
525:            /**
526:             * Gets the default encoding for converting bytes to characters when
527:             * reading template files in a locale for which no explicit encoding
528:             * was specified. Defaults to default system encoding.
529:             */
530:            public String getDefaultEncoding() {
531:                return defaultEncoding;
532:            }
533:
534:            /**
535:             * Gets the preferred character encoding for the given locale, or the 
536:             * default encoding if no encoding is set explicitly for the specified
537:             * locale. You can associate encodings with locales using 
538:             * {@link #setEncoding(Locale, String)} or {@link #loadBuiltInEncodingMap()}.
539:             * @param loc the locale
540:             * @return the preferred character encoding for the locale.
541:             */
542:            public String getEncoding(Locale loc) {
543:                // Try for a full name match (may include country and variant)
544:                String charset = (String) encodingMap.get(loc.toString());
545:                if (charset == null) {
546:                    if (loc.getVariant().length() > 0) {
547:                        Locale l = new Locale(loc.getLanguage(), loc
548:                                .getCountry());
549:                        charset = (String) encodingMap.get(l.toString());
550:                        if (charset != null) {
551:                            encodingMap.put(loc.toString(), charset);
552:                        }
553:                    }
554:                    charset = (String) encodingMap.get(loc.getLanguage());
555:                    if (charset != null) {
556:                        encodingMap.put(loc.toString(), charset);
557:                    }
558:                }
559:                return charset != null ? charset : defaultEncoding;
560:            }
561:
562:            /**
563:             * Sets the character set encoding to use for templates of
564:             * a given locale. If there is no explicit encoding set for some
565:             * locale, then the default encoding will be used, what you can
566:             * set with {@link #setDefaultEncoding}.
567:             *
568:             * @see #clearEncodingMap
569:             * @see #loadBuiltInEncodingMap
570:             */
571:            public void setEncoding(Locale locale, String encoding) {
572:                encodingMap.put(locale.toString(), encoding);
573:            }
574:
575:            /**
576:             * Adds a shared variable to the configuration.
577:             * Shared variables are variables that are visible
578:             * as top-level variables for all templates which use this
579:             * configuration, if the data model does not contain a
580:             * variable with the same name.
581:             *
582:             * <p>Never use <tt>TemplateModel</tt> implementation that is not thread-safe for shared variables,
583:             * if the configuration is used by multiple threads! It is the typical situation for Servlet based Web sites.
584:             *
585:             * @param name the name used to access the data object from your template.
586:             *     If a shared variable with this name already exists, it will replace
587:             *     that.
588:             * @see #setSharedVariable(String,Object)
589:             * @see #setAllSharedVariables
590:             */
591:            public void setSharedVariable(String name, TemplateModel tm) {
592:                variables.put(name, tm);
593:            }
594:
595:            /**
596:             * Returns the set containing the names of all defined shared variables.
597:             * The method returns a new Set object on each call that is completely
598:             * disconnected from the Configuration. That is, modifying the set will have
599:             * no effect on the Configuration object.
600:             */
601:            public Set getSharedVariableNames() {
602:                return new HashSet(variables.keySet());
603:            }
604:
605:            /**
606:             * Adds shared variable to the configuration.
607:             * It uses {@link Configurable#getObjectWrapper()} to wrap the 
608:             * <code>obj</code>.
609:             * @see #setSharedVariable(String,TemplateModel)
610:             * @see #setAllSharedVariables
611:             */
612:            public void setSharedVariable(String name, Object obj)
613:                    throws TemplateModelException {
614:                setSharedVariable(name, getObjectWrapper().wrap(obj));
615:            }
616:
617:            /**
618:             * Adds all object in the hash as shared variable to the configuration.
619:             *
620:             * <p>Never use <tt>TemplateModel</tt> implementation that is not thread-safe for shared variables,
621:             * if the configuration is used by multiple threads! It is the typical situation for Servlet based Web sites.
622:             *
623:             * @param hash a hash model whose objects will be copied to the
624:             * configuration with same names as they are given in the hash.
625:             * If a shared variable with these names already exist, it will be replaced
626:             * with those from the map.
627:             *
628:             * @see #setSharedVariable(String,Object)
629:             * @see #setSharedVariable(String,TemplateModel)
630:             */
631:            public void setAllSharedVariables(TemplateHashModelEx hash)
632:                    throws TemplateModelException {
633:                TemplateModelIterator keys = hash.keys().iterator();
634:                TemplateModelIterator values = hash.values().iterator();
635:                while (keys.hasNext()) {
636:                    setSharedVariable(((TemplateScalarModel) keys.next())
637:                            .getAsString(), values.next());
638:                }
639:            }
640:
641:            /**
642:             * Gets a shared variable. Shared variables are variables that are 
643:             * available to all templates. When a template is processed, and an identifier
644:             * is undefined in the data model, a shared variable object with the same identifier
645:             * is then looked up in the configuration. There are several predefined variables
646:             * that are always available through this method, see the FreeMarker manual
647:             * for a comprehensive list of them.
648:             *
649:             * @see #setSharedVariable(String,Object)
650:             * @see #setSharedVariable(String,TemplateModel)
651:             * @see #setAllSharedVariables
652:             */
653:            public TemplateModel getSharedVariable(String name) {
654:                return (TemplateModel) variables.get(name);
655:            }
656:
657:            /**
658:             * Removes all shared variables, except the predefined ones (compress, html_escape, etc.).
659:             */
660:            public void clearSharedVariables() {
661:                variables.clear();
662:                loadBuiltInSharedVariables();
663:            }
664:
665:            /**
666:             * Removes all entries from the template cache, thus forcing reloading of templates
667:             * on subsequent <code>getTemplate</code> calls.
668:             * This method is thread-safe and can be called while the engine works.
669:             */
670:            public void clearTemplateCache() {
671:                cache.clear();
672:            }
673:
674:            /**
675:             * Returns if localized template lookup is enabled or not.
676:             * This method is thread-safe and can be called while the engine works.
677:             */
678:            public boolean getLocalizedLookup() {
679:                return cache.getLocalizedLookup();
680:            }
681:
682:            /**
683:             * Enables/disables localized template lookup. Enabled by default.
684:             * This method is thread-safe and can be called while the engine works.
685:             */
686:            public void setLocalizedLookup(boolean localizedLookup) {
687:                this .localizedLookup = localizedLookup;
688:                cache.setLocalizedLookup(localizedLookup);
689:            }
690:
691:            /**
692:             * Sets a setting by name and string value.
693:             *
694:             * In additional to the settings understood by
695:             * {@link Configurable#setSetting the super method}, it understands these:
696:             * <ul>
697:             *   <li><code>"auto_import"</code>: Sets the list of auto-imports. Example of valid value:
698:             *       <br><code>/lib/form.ftl as f, /lib/widget as w, "/lib/evil name.ftl" as odd</code>
699:             *       See: {@link #setAutoImports}
700:             *   <li><code>"auto_include"</code>: Sets the list of auto-includes. Example of valid value:
701:             *       <br><code>/include/common.ftl, "/include/evil name.ftl"</code>
702:             *       See: {@link #setAutoIncludes}
703:             *   <li><code>"default_encoding"</code>: The name of the charset, such as <code>"UTF-8"</code>.
704:             *       See: {@link #setDefaultEncoding}
705:             *   <li><code>"localized_lookup"</code>:
706:             *       <code>"true"</code>, <code>"false"</code>, <code>"yes"</code>, <code>"no"</code>,
707:             *       <code>"t"</code>, <code>"f"</code>, <code>"y"</code>, <code>"n"</code>.
708:             *       Case insensitive.
709:             *      See: {@link #setLocalizedLookup}
710:             *   <li><code>"strict_syntax"</code>: <code>"true"</code>, <code>"false"</code>, etc.
711:             *       See: {@link #setStrictSyntaxMode}
712:             *   <li><code>"whitespace_stripping"</code>: <code>"true"</code>, <code>"false"</code>, etc.
713:             *       See: {@link #setWhitespaceStripping}
714:             *   <li><code>"cache_storage"</code>: If the value contains dot, then it is
715:             *       interpreted as class name, and the object will be created with
716:             *       its parameterless constructor. If the value does not contain dot,
717:             *       then a {@link freemarker.cache.MruCacheStorage} will be used with the
718:             *       maximum strong and soft sizes specified with the setting value. Examples
719:             *       of valid setting values:
720:             *       <table border=1 cellpadding=4>
721:             *         <tr><th>Setting value<th>max. strong size<th>max. soft size
722:             *         <tr><td><code>"strong:50, soft:500"</code><td>50<td>500
723:             *         <tr><td><code>"strong:100, soft"</code><td>100<td><code>Integer.MAX_VALUE</code>
724:             *         <tr><td><code>"strong:100"</code><td>100<td>0
725:             *         <tr><td><code>"soft:100"</code><td>0<td>100
726:             *         <tr><td><code>"strong"</code><td><code>Integer.MAX_VALUE</code><td>0
727:             *         <tr><td><code>"soft"</code><td>0<td><code>Integer.MAX_VALUE</code>
728:             *       </table>
729:             *       The value is not case sensitive. The order of <tt>soft</tt> and <tt>strong</tt>
730:             *       entries is not significant.
731:             *       See also: {@link #setCacheStorage}
732:             *   <li><code>"template_update_delay"</code>: Valid positive integer, the
733:             *       update delay measured in seconds.
734:             *       See: {@link #setTemplateUpdateDelay}
735:             *   <li><code>"tag_syntax"</code>: Must be one of:
736:             *       <code>"auto_detect"</code>, <code>"angle_bracket"</code>,
737:             *       <code>"square_bracket"</code>.
738:             * </ul>
739:             *
740:             * @param key the name of the setting.
741:             * @param value the string that describes the new value of the setting.
742:             *
743:             * @throws UnknownSettingException if the key is wrong.
744:             * @throws TemplateException if the new value of the setting can't be set
745:             *     for any other reasons.
746:             */
747:            public void setSetting(String key, String value)
748:                    throws TemplateException {
749:                if ("TemplateUpdateInterval".equalsIgnoreCase(key)) {
750:                    key = TEMPLATE_UPDATE_DELAY_KEY;
751:                } else if ("DefaultEncoding".equalsIgnoreCase(key)) {
752:                    key = DEFAULT_ENCODING_KEY;
753:                }
754:                try {
755:                    if (DEFAULT_ENCODING_KEY.equals(key)) {
756:                        setDefaultEncoding(value);
757:                    } else if (LOCALIZED_LOOKUP_KEY.equals(key)) {
758:                        setLocalizedLookup(StringUtil.getYesNo(value));
759:                    } else if (STRICT_SYNTAX_KEY.equals(key)) {
760:                        setStrictSyntaxMode(StringUtil.getYesNo(value));
761:                    } else if (WHITESPACE_STRIPPING_KEY.equals(key)) {
762:                        setWhitespaceStripping(StringUtil.getYesNo(value));
763:                    } else if (CACHE_STORAGE_KEY.equals(key)) {
764:                        if (value.indexOf('.') == -1) {
765:                            int strongSize = 0;
766:                            int softSize = 0;
767:                            Map map = StringUtil.parseNameValuePairList(value,
768:                                    String.valueOf(Integer.MAX_VALUE));
769:                            Iterator it = map.entrySet().iterator();
770:                            while (it.hasNext()) {
771:                                Map.Entry ent = (Map.Entry) it.next();
772:                                String pname = (String) ent.getKey();
773:                                int pvalue;
774:                                try {
775:                                    pvalue = Integer.parseInt((String) ent
776:                                            .getValue());
777:                                } catch (NumberFormatException e) {
778:                                    throw invalidSettingValueException(key,
779:                                            value);
780:                                }
781:                                if ("soft".equalsIgnoreCase(pname)) {
782:                                    softSize = pvalue;
783:                                } else if ("strong".equalsIgnoreCase(pname)) {
784:                                    strongSize = pvalue;
785:                                } else {
786:                                    throw invalidSettingValueException(key,
787:                                            value);
788:                                }
789:                            }
790:                            if (softSize == 0 && strongSize == 0) {
791:                                throw invalidSettingValueException(key, value);
792:                            }
793:                            setCacheStorage(new MruCacheStorage(strongSize,
794:                                    softSize));
795:                        } else {
796:                            setCacheStorage((CacheStorage) ClassUtil.forName(
797:                                    value).newInstance());
798:                        }
799:                    } else if (TEMPLATE_UPDATE_DELAY_KEY.equals(key)) {
800:                        setTemplateUpdateDelay(Integer.parseInt(value));
801:                    } else if (AUTO_INCLUDE_KEY.equals(key)) {
802:                        setAutoIncludes(new SettingStringParser(value)
803:                                .parseAsList());
804:                    } else if (AUTO_IMPORT_KEY.equals(key)) {
805:                        setAutoImports(new SettingStringParser(value)
806:                                .parseAsImportList());
807:                    } else if (TAG_SYNTAX_KEY.equals(key)) {
808:                        if ("auto_detect".equals(value)) {
809:                            setTagSyntax(AUTO_DETECT_TAG_SYNTAX);
810:                        } else if ("angle_bracket".equals(value)) {
811:                            setTagSyntax(ANGLE_BRACKET_TAG_SYNTAX);
812:                        } else if ("square_bracket".equals(value)) {
813:                            setTagSyntax(SQUARE_BRACKET_TAG_SYNTAX);
814:                        } else {
815:                            throw invalidSettingValueException(key, value);
816:                        }
817:                    } else {
818:                        super .setSetting(key, value);
819:                    }
820:                } catch (Exception e) {
821:                    throw new TemplateException("Failed to set setting " + key
822:                            + " to value " + value, e, getEnvironment());
823:                }
824:            }
825:
826:            /**
827:             * Add an auto-imported template.
828:             * The importing will happen at the top of any template that
829:             * is vended by this Configuration object.
830:             * @param namespace the name of the namespace into which the template is imported
831:             * @param template the name of the template
832:             */
833:            public synchronized void addAutoImport(String namespace,
834:                    String template) {
835:                autoImports.remove(namespace);
836:                autoImports.add(namespace);
837:                autoImportMap.put(namespace, template);
838:            }
839:
840:            /**
841:             * Remove an auto-imported template
842:             * @param namespace the name of the namespace into which the template was imported
843:             */
844:
845:            public synchronized void removeAutoImport(String namespace) {
846:                autoImports.remove(namespace);
847:                autoImportMap.remove(namespace);
848:            }
849:
850:            /**
851:             * set a map of namespace names to templates for auto-importing 
852:             * a set of templates. Note that all previous auto-imports are removed.
853:             */
854:
855:            public synchronized void setAutoImports(Map map) {
856:                autoImports = new ArrayList(map.keySet());
857:                if (map instanceof  HashMap) {
858:                    autoImportMap = (Map) ((HashMap) map).clone();
859:                } else if (map instanceof  SortedMap) {
860:                    autoImportMap = new TreeMap(map);
861:                } else {
862:                    autoImportMap = new HashMap(map);
863:                }
864:            }
865:
866:            void doAutoImports(Environment env) throws TemplateException,
867:                    IOException {
868:                for (int i = 0; i < autoImports.size(); i++) {
869:                    String namespace = (String) autoImports.get(i);
870:                    String templateName = (String) autoImportMap.get(namespace);
871:                    env.importLib(templateName, namespace);
872:                }
873:            }
874:
875:            /**
876:             * add a template to be automatically included at the top of any template that
877:             * is vended by this Configuration object.
878:             * @param templateName the lookup name of the template.
879:             */
880:
881:            public synchronized void addAutoInclude(String templateName) {
882:                autoIncludes.remove(templateName);
883:                autoIncludes.add(templateName);
884:            }
885:
886:            /**
887:             * set the list of automatically included templates.
888:             * Note that all previous auto-includes are removed.
889:             */
890:            public synchronized void setAutoIncludes(List templateNames) {
891:                autoIncludes.clear();
892:                Iterator it = templateNames.iterator();
893:                while (it.hasNext()) {
894:                    Object o = it.next();
895:                    if (!(o instanceof  String)) {
896:                        throw new IllegalArgumentException(
897:                                "List items must be String-s.");
898:                    }
899:                    autoIncludes.add(o);
900:                }
901:            }
902:
903:            /**
904:             * remove a template from the auto-include list.
905:             * @param templateName the lookup name of the template in question.
906:             */
907:
908:            public synchronized void removeAutoInclude(String templateName) {
909:                autoIncludes.remove(templateName);
910:            }
911:
912:            /**
913:             * Returns FreeMarker version number string. 
914:             * Examples of possible return values:
915:             * <code>"2.2.5"</code>, <code>"2.3pre13"</code>,
916:             * <code>"2.3pre13mod"</code>, <code>"2.3rc1"</code>, <code>"2.3"</code>,
917:             * <code>"3.0"</code>.
918:             *
919:             * <p>Notes on FreeMarker version numbering rules:
920:             * <ul>
921:             *   <li>"pre" and "rc" (lowercase!) means "preview" and "release
922:             *       candidate" respectively. It is must be followed with a
923:             *       number (as "1" for the first release candidate).
924:             *   <li>The "mod" after the version number indicates that it's an
925:             *       unreleased modified version of the released version.
926:             *       After releases, the nighly builds are such releases. E.g.
927:             *       the nightly build after releasing "2.2.1" but before releasing
928:             *       "2.2.2" is "2.2.1mod".
929:             *   <li>The 2nd version number must be present, and maybe 0,
930:             *       as in "3.0".
931:             *   <li>The 3rd version number is never 0. E.g. the version
932:             *       number string for the first release of the 2.2 series
933:             *       is "2.2", and NOT "2.2.0". 
934:             *   <li>When only the 3rd version number increases
935:             *       (2.2 -> 2.2.1, 2.2.1 -> 2.2.2 etc.), 100% backward compatiblity
936:             *       with the previous version MUST be kept.
937:             *       This means that <tt>freemarker.jar</tt> can be replaced in an
938:             *       application without risk (as far as the application doesn't depend
939:             *       on the presence of a FreeMarker bug).
940:             *       Note that backward compatibility restrictions do not apply for
941:             *       preview releases.
942:             * </ul>
943:             */
944:            public static String getVersionNumber() {
945:                if (cachedVersion != null) {
946:                    return cachedVersion;
947:                }
948:                try {
949:                    Properties vp = new Properties();
950:                    InputStream ins = Configuration.class.getClassLoader()
951:                            .getResourceAsStream(
952:                                    "freemarker/version.properties");
953:                    if (ins == null) {
954:                        throw new RuntimeException("Version file is missing.");
955:                    } else {
956:                        try {
957:                            vp.load(ins);
958:                        } finally {
959:                            ins.close();
960:                        }
961:                        String v = vp.getProperty("version");
962:                        if (v == null) {
963:                            throw new RuntimeException(
964:                                    "Version file is corrupt: version key is missing.");
965:                        }
966:                        cachedVersion = v;
967:                    }
968:                    return cachedVersion;
969:                } catch (IOException e) {
970:                    throw new RuntimeException("Failed to load version file: "
971:                            + e);
972:                }
973:            }
974:
975:            void doAutoIncludes(Environment env) throws TemplateException,
976:                    IOException {
977:                for (int i = 0; i < autoIncludes.size(); i++) {
978:                    String templateName = (String) autoIncludes.get(i);
979:                    Template template = getTemplate(templateName, env
980:                            .getLocale());
981:                    env.include(template);
982:                }
983:            }
984:
985:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.