Como #incluir um arquivo de um modelo Velocity usando ClasspathResourceLoader
Estou lidando com algum código Java em que o Velocity 1.7 está definido para recuperar modelos por meio do ClasspathResourceLoader. Abaixo está uma amostra simplificada do código. É de um aplicativo Web Tapeestry em execução em um servidor Jetty.
A classe Java, os modelos e o arquivo a ser incluído estão todos na mesma pasta "testpackage", portanto, no JAR resultante, todos estão no mesmo pacote "testpackage".
O problema é que, se o modelo contiver um
#include("MyInclude.vm")
diretiva, o Velocity não pode encontrar "MyInclude.vm" e lança uma ResourceNotFoundException.
Como no argumento de getTemplate eu devo acrescentar o nome do pacote ao nome do modelo, também tentei fazer o mesmo no #include dentro do modelo:
#include("testpackage/MyInclude.vm")
mas a única diferença é que o último funciona se eu executar o aplicativo Web do Eclipse, enquanto o primeiro nem funciona, nem mesmo no Eclipse. Se eu construir, implantar os JARs e executar o aplicativo Web a partir da implantação, ambas as sintaxes falharão com a mesma ResourceNotFoundException.
O documento Velocity emhttp://velocity.apache.org/engine/releases/velocity-1.7/user-guide.html#Include diz:
"Por motivos de segurança, o arquivo a ser incluído pode estar apenas em TEMPLATE_ROOT"
Definitivamente, isso pode ser a causa do meu problema, mas não consegui encontrar mais informações sobre o que realmente é TEMPLATE_ROOT.
Parece muito com uma variável de ambiente, mas não sei como devo defini-la, pois estou usando um ClasspathResourceLoader e o arquivo a ser incluído não é um arquivo real localizado em uma pasta, está dentro do JAR contendo os modelos e a classe Java (e todos no mesmo pacote).
Encontrei TEMPLATE_ROOT mencionado em outra pergunta,Onde devo colocar os arquivos de modelo do Velocity para um utilitário de linha de comando criado com o Maven? , mas está relacionado ao uso de um FileResourceLoader. Preciso continuar usando o ClasspathResourceLoader e preciso que todos os arquivos estejam no JAR, não fora dele como arquivos normais em alguma pasta.
TestVelocity.javapackage testpackage;
import java.io.StringWriter;
import java.util.Properties;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;
public class TestVelocity
{
public static String getText()
{
String text = "";
Properties properties = new Properties();
properties.setProperty("resource.loader", "class");
properties.setProperty("class.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
VelocityEngine engine = new VelocityEngine();
VelocityContext context = new VelocityContext();
StringWriter writer = new StringWriter();
try
{
engine.init(properties);
// This works because the template doesn't contain any #include
Template template = engine.getTemplate("testpackage/TemplateWithoutInclude.vm");
// This causes ResourceNotFoundException: Unable to find resource 'TemplateWithInclude.vm'
// Template template = engine.getTemplate("testpackage/TemplateWithInclude.vm");
template.merge(context, writer);
text = writer.toString();
}
catch (Exception e)
{
e.printStackTrace();
}
return text;
}
}
TemplateWithoutInclude.vm<!DOCTYPE html>
<html>
<head></head>
<body>
<p>Hello</p>
</body>
</html>
TemplateWithInclude.vm<!DOCTYPE html>
<html>
<head></head>
<body>
#include("MyInclude.vm")
</body>
</html>
MyInclude.vm<p>
Hello
</p>