1 16 17 package org.springframework.ui.freemarker; 18 19 import java.io.File ; 20 import java.io.IOException ; 21 import java.util.ArrayList ; 22 import java.util.Arrays ; 23 import java.util.List ; 24 import java.util.Map ; 25 import java.util.Properties ; 26 27 import freemarker.cache.FileTemplateLoader; 28 import freemarker.cache.MultiTemplateLoader; 29 import freemarker.cache.TemplateLoader; 30 import freemarker.template.Configuration; 31 import freemarker.template.SimpleHash; 32 import freemarker.template.TemplateException; 33 import org.apache.commons.logging.Log; 34 import org.apache.commons.logging.LogFactory; 35 36 import org.springframework.core.io.DefaultResourceLoader; 37 import org.springframework.core.io.Resource; 38 import org.springframework.core.io.ResourceLoader; 39 import org.springframework.core.io.support.PropertiesLoaderUtils; 40 import org.springframework.util.CollectionUtils; 41 42 75 public class FreeMarkerConfigurationFactory { 76 77 protected final Log logger = LogFactory.getLog(getClass()); 78 79 private Resource configLocation; 80 81 private Properties freemarkerSettings; 82 83 private Map freemarkerVariables; 84 85 private String defaultEncoding; 86 87 private final List templateLoaders = new ArrayList (); 88 89 private List preTemplateLoaders; 90 91 private List postTemplateLoaders; 92 93 private String [] templateLoaderPaths; 94 95 private ResourceLoader resourceLoader = new DefaultResourceLoader(); 96 97 private boolean preferFileSystemAccess = true; 98 99 100 106 public void setConfigLocation(Resource resource) { 107 configLocation = resource; 108 } 109 110 115 public void setFreemarkerSettings(Properties settings) { 116 this.freemarkerSettings = settings; 117 } 118 119 124 public void setFreemarkerVariables(Map variables) { 125 this.freemarkerVariables = variables; 126 } 127 128 136 public void setDefaultEncoding(String defaultEncoding) { 137 this.defaultEncoding = defaultEncoding; 138 } 139 140 149 public void setTemplateLoaders(TemplateLoader[] templateLoaders) { 150 if (templateLoaders != null) { 151 this.templateLoaders.addAll(Arrays.asList(templateLoaders)); 152 } 153 } 154 155 166 public void setPreTemplateLoaders(TemplateLoader[] preTemplateLoaders) { 167 this.preTemplateLoaders = Arrays.asList(preTemplateLoaders); 168 } 169 170 181 public void setPostTemplateLoaders(TemplateLoader[] postTemplateLoaders) { 182 this.postTemplateLoaders = Arrays.asList(postTemplateLoaders); 183 } 184 185 190 public void setTemplateLoaderPath(String templateLoaderPath) { 191 this.templateLoaderPaths = new String [] {templateLoaderPath}; 192 } 193 194 213 public void setTemplateLoaderPaths(String [] templateLoaderPaths) { 214 this.templateLoaderPaths = templateLoaderPaths; 215 } 216 217 223 public void setResourceLoader(ResourceLoader resourceLoader) { 224 this.resourceLoader = resourceLoader; 225 } 226 227 230 protected ResourceLoader getResourceLoader() { 231 return resourceLoader; 232 } 233 234 246 public void setPreferFileSystemAccess(boolean preferFileSystemAccess) { 247 this.preferFileSystemAccess = preferFileSystemAccess; 248 } 249 250 253 protected boolean isPreferFileSystemAccess() { 254 return preferFileSystemAccess; 255 } 256 257 258 264 public Configuration createConfiguration() throws IOException , TemplateException { 265 Configuration config = newConfiguration(); 266 Properties props = new Properties (); 267 268 if (this.configLocation != null) { 270 if (logger.isInfoEnabled()) { 271 logger.info("Loading FreeMarker configuration from " + this.configLocation); 272 } 273 PropertiesLoaderUtils.fillProperties(props, this.configLocation); 274 } 275 276 if (this.freemarkerSettings != null) { 278 props.putAll(this.freemarkerSettings); 279 } 280 281 if (!props.isEmpty()) { 284 config.setSettings(props); 285 } 286 287 if (!CollectionUtils.isEmpty(this.freemarkerVariables)) { 288 config.setAllSharedVariables(new SimpleHash(this.freemarkerVariables)); 289 } 290 291 if (this.defaultEncoding != null) { 292 config.setDefaultEncoding(this.defaultEncoding); 293 } 294 295 if (this.preTemplateLoaders != null) { 297 this.templateLoaders.addAll(this.preTemplateLoaders); 298 } 299 300 if (this.templateLoaderPaths != null) { 302 for (int i = 0; i < this.templateLoaderPaths.length; i++) { 303 this.templateLoaders.add(getTemplateLoaderForPath(this.templateLoaderPaths[i])); 304 } 305 } 306 postProcessTemplateLoaders(this.templateLoaders); 307 308 if (this.postTemplateLoaders != null) { 310 this.templateLoaders.addAll(this.postTemplateLoaders); 311 } 312 313 TemplateLoader loader = getAggregateTemplateLoader(this.templateLoaders); 314 if (loader != null) { 315 config.setTemplateLoader(loader); 316 } 317 318 postProcessConfiguration(config); 319 return config; 320 } 321 322 331 protected Configuration newConfiguration() throws IOException , TemplateException { 332 return new Configuration(); 333 } 334 335 344 protected TemplateLoader getTemplateLoaderForPath(String templateLoaderPath) { 345 if (isPreferFileSystemAccess()) { 346 try { 349 Resource path = getResourceLoader().getResource(templateLoaderPath); 350 File file = path.getFile(); if (logger.isDebugEnabled()) { 352 logger.debug( 353 "Template loader path [" + path + "] resolved to file path [" + file.getAbsolutePath() + "]"); 354 } 355 return new FileTemplateLoader(file); 356 } 357 catch (IOException ex) { 358 if (logger.isDebugEnabled()) { 359 logger.debug("Cannot resolve template loader path [" + templateLoaderPath + 360 "] to [java.io.File]: using SpringTemplateLoader as fallback", ex); 361 } 362 return new SpringTemplateLoader(getResourceLoader(), templateLoaderPath); 363 } 364 } 365 else { 366 logger.debug("File system access not preferred: using SpringTemplateLoader"); 368 return new SpringTemplateLoader(getResourceLoader(), templateLoaderPath); 369 } 370 } 371 372 385 protected void postProcessTemplateLoaders(List templateLoaders) { 386 } 387 388 395 protected TemplateLoader getAggregateTemplateLoader(List templateLoaders) { 396 int loaderCount = templateLoaders.size(); 397 switch (loaderCount) { 398 case 0: 399 logger.info("No FreeMarker TemplateLoaders specified"); 400 return null; 401 case 1: 402 return (TemplateLoader) templateLoaders.get(0); 403 default: 404 TemplateLoader[] loaders = (TemplateLoader[]) templateLoaders.toArray(new TemplateLoader[loaderCount]); 405 return new MultiTemplateLoader(loaders); 406 } 407 } 408 409 419 protected void postProcessConfiguration(Configuration config) throws IOException , TemplateException { 420 } 421 422 } 423 | Popular Tags |