/*
* Copyright (C) 2010-2012 Stichting Akvo (Akvo Foundation)
*
* This file is part of Akvo FLOW.
*
* Akvo FLOW is free software: you can redistribute it and modify it under the terms of
* the GNU Affero General Public License (AGPL) as published by the Free Software Foundation,
* either version 3 of the License or any later version.
*
* Akvo FLOW is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Affero General Public License included below for more details.
*
* The full license text can also be seen at <http://www.gnu.org/licenses/agpl.html>.
*/
package com.gallatinsystems.common.util;
import java.io.StringWriter;
import java.util.Collections;
import java.util.logging.Level;
import java.util.logging.Logger;
import net.sf.jsr107cache.Cache;
import net.sf.jsr107cache.CacheException;
import net.sf.jsr107cache.CacheManager;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;
/**
* Utility for interacting with the Velocity engine.
*
* @author Christopher Fagiani
*/
public class VelocityUtil {
private static final Logger log = Logger.getLogger(VelocityUtil.class
.getName());
private static Cache templateCache;
public static final String CACHE_KEY_PREFIX = "VELOCITY_TEMPLATE/";
static {
Velocity.setProperty("runtime.log.logsystem.class",
"org.apache.velocity.runtime.log.NullLogChute");
try {
Velocity.init();
} catch (Exception e) {
log.log(Level.SEVERE, "Could not initialize velocity", e);
}
try {
templateCache = CacheManager.getInstance().getCacheFactory()
.createCache(Collections.EMPTY_MAP);
} catch (CacheException e) {
log.log(Level.SEVERE, "Could not initialize cache", e);
}
}
/**
* merges a hydrated context with a template identified by the templateName passed in.
*
* @param context
* @param templaet
* @return
* @throws Exception
*/
public static String mergeContext(VelocityContext context,
String templateName) throws Exception {
return mergeContext(context, templateName, null);
}
/**
* merges a hydrated context with a template identified by the template name. The template will
* be resolved in the following order: the Cache will be checked. If not found, the backingStore
* will be queried (if backingStore is not null) then, if still not found, it will look for a
* file with the name matching the template file.
*
* @param context
* @param templateName
* @param backingStore
* @return
* @throws Exception
*/
public static String mergeContext(VelocityContext context,
String templateName, TemplateCacheBackingStore backingStore)
throws Exception {
String templateText = (String) templateCache.get(CACHE_KEY_PREFIX
+ templateName);
StringWriter writer = new StringWriter();
if (templateText == null && backingStore != null) {
templateText = backingStore.getByKey(templateName);
if (templateText != null) {
templateCache
.put(CACHE_KEY_PREFIX + templateName, templateText);
}
}
if (templateText == null) {
Template t = Velocity.getTemplate(templateName);
t.merge(context, writer);
} else {
Velocity.evaluate(context, writer, templateName, templateText);
}
return writer.toString();
}
/**
* Implementors of this interface know how to look up the content identified by the key passed
* in in the persistent store (to handle a cache miss).
*
* @author Christopher Fagiani
*/
public interface TemplateCacheBackingStore {
public String getByKey(String key);
}
}