All Downloads are FREE. Search and download functionalities are using the official Maven repository.

freemarker.cache.StringTemplateLoader Maven / Gradle / Ivy

There is a newer version: 7.0.58
Show newest version
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package freemarker.cache;

import java.io.Reader;
import java.io.StringReader;
import java.util.HashMap;
import java.util.Map;

import freemarker.template.utility.StringUtil;

/**
 * A {@link TemplateLoader} that uses a {@link Map} with {@link String}-s as its source of 
 * templates.
 *
 * 

In most case the regular way of loading templates from files will be fine. * However, there can be situations where you don't want to or can't load a * template from a file, e.g. if you have to deploy a single jar for * JavaWebStart or if they are contained within a database. * A single template can be created manually * e.g. *

 *   String templateStr="Hello ${user}";
 *   Template t = new Template("name", new StringReader(templateStr),
 *               new Configuration());
 * 
*

If, however, you want to create templates from strings which import other * templates this method doesn't work. * *

In that case you can create a StringTemplateLoader and add each template to * it: *

 *   StringTemplateLoader stringLoader = new StringTemplateLoader();
 *   stringLoader.putTemplate("greetTemplate", "<#macro greet>Hello</#macro>");
 *   stringLoader.putTemplate("myTemplate", "<#include \"greetTemplate\"><@greet/> World!");
 * 
*

Then you tell your Configuration object to use it: *

 *   cfg.setTemplateLoader(stringLoader);
 * 
*

After that you should be able to use the templates as usual. Often you will * want to combine a StringTemplateLoader with another loader. You can * do so using a {@link freemarker.cache.MultiTemplateLoader}. */ public class StringTemplateLoader implements TemplateLoader { private final Map templates = new HashMap<>(); /** * Puts a template into the loader. A call to this method is identical to * the call to the three-arg {@link #putTemplate(String, String, long)} * passing System.currentTimeMillis() as the third argument. * *

Note that this method is not thread safe! Don't call it after FreeMarker has started using this template * loader. * * @param name the name of the template. * @param templateContent the source code of the template. */ public void putTemplate(String name, String templateContent) { putTemplate(name, templateContent, System.currentTimeMillis()); } /** * Puts a template into the loader. The name can contain slashes to denote * logical directory structure, but must not start with a slash. If the * method is called multiple times for the same name and with different * last modified time, the configuration's template cache will reload the * template according to its own refresh settings (note that if the refresh * is disabled in the template cache, the template will not be reloaded). * Also, since the cache uses lastModified to trigger reloads, calling the * method with different source and identical timestamp won't trigger * reloading. * *

Note that this method is not thread safe! Don't call it after FreeMarker has started using this template * loader. * * @param name the name of the template. * @param templateContent the source code of the template. * @param lastModified the time of last modification of the template in * terms of System.currentTimeMillis() */ public void putTemplate(String name, String templateContent, long lastModified) { templates.put(name, new StringTemplateSource(name, templateContent, lastModified)); } /** * Removes the template with the specified name if it was added earlier. * *

Note that this method is not thread safe! Don't call it after FreeMarker has started using this template * loader. * * @param name Exactly the key with which the template was added. * * @return Whether a template was found with the given key (and hence was removed now) * * @since 2.3.24 */ public boolean removeTemplate(String name) { return templates.remove(name) != null; } @Override public void closeTemplateSource(Object templateSource) { } @Override public Object findTemplateSource(String name) { return templates.get(name); } @Override public long getLastModified(Object templateSource) { return ((StringTemplateSource) templateSource).lastModified; } @Override public Reader getReader(Object templateSource, String encoding) { return new StringReader(((StringTemplateSource) templateSource).templateContent); } private static class StringTemplateSource { private final String name; private final String templateContent; private final long lastModified; StringTemplateSource(String name, String templateContent, long lastModified) { if (name == null) { throw new IllegalArgumentException("name == null"); } if (templateContent == null) { throw new IllegalArgumentException("source == null"); } if (lastModified < -1L) { throw new IllegalArgumentException("lastModified < -1L"); } this.name = name; this.templateContent = templateContent; this.lastModified = lastModified; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((name == null) ? 0 : name.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; StringTemplateSource other = (StringTemplateSource) obj; if (name == null) { if (other.name != null) return false; } else if (!name.equals(other.name)) return false; return true; } @Override public String toString() { return name; } } /** * Show class name and some details that are useful in template-not-found errors. * * @since 2.3.21 */ @Override public String toString() { StringBuilder sb = new StringBuilder(); sb.append(TemplateLoaderUtils.getClassNameForToString(this)); sb.append("(Map { "); int cnt = 0; for (String name : templates.keySet()) { cnt++; if (cnt != 1) { sb.append(", "); } if (cnt > 10) { sb.append("..."); break; } sb.append(StringUtil.jQuote(name)); sb.append("=..."); } if (cnt != 0) { sb.append(' '); } sb.append("})"); return sb.toString(); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy