Скорость в OSGi: как загрузить шаблоны из classpath - PullRequest
9 голосов
/ 22 декабря 2011

Я разрабатываю приложение для OSGi с движком шаблонов скорости.Он отлично работает для загрузки моих шаблонов с помощью загрузчика файлов, но теперь я должен внедрить эти шаблоны в свой jar-файл и загрузить его как ресурсы.

Как я могу заставить его работать?

Мой код:

ve = new VelocityEngine();
ve.setProperty(RuntimeConstants.RESOURCE_LOADER, "classpath");
ve.setProperty("classpath.resource.loader.class", 
    ClasspathResourceLoader.class.getName());
ve.setProperty("classpath.resource.loader.path", "/velocitytemplates");
ve.init();

ve.getTemplate("foo.vm");

Это вызовет исключение, подобное

Невозможно найти ресурс 'index.vm'

Причина:

org.apache.velocity.exception.ResourceNotFoundException: Невозможно найти ресурс 'index.vm'

Ответы [ 4 ]

8 голосов
/ 11 июля 2012

К сожалению, скорость не настолько дружелюбна к OSGi.Поэтому вы не можете использовать встроенный ClasspathResourceLoader, и трудно также добавить специально разработанный ResourceLoader.

Я предлагаю вам получить ваш шаблон в качестве Reader любым из обычных способов и выбрать один из следующих:

  • Используйте функцию расширения VelocityEngine, если вам нужно редко объединять шаблон (производительность не имеет большого значения)
  • Создать шаблон вручную с внутренними классами Velocity

Первый вариант можно использовать, если вам не нужно часто объединять шаблоны, поэтому производительность не является ключевым требованием.

Вот пример для второго варианта, где создается шаблонОбъект можно использовать повторно, вызвав для него функцию слияния (ожидая, что у вас уже есть Reader для вашего файла или ресурса vm):

RuntimeInstance runtimeInstance = new RuntimeInstance();
runtimeInstance.init();
SimpleNode simpleNode = runtimeInstance.parse(reader, "nameOfYourTemplateResource");

Template template = new Template();
simpleNode.init(new InternalContextAdapterImpl(new VelocityContext()), runtimeInstance);
template.setData(simpleNode);

template.merge(...);
...

Чтобы получить читателя для файла vm в OSGi, вам нужно выбратькласс, который обязательно находится в том же пакете, что и ресурс vm, и вызывает SameBundleClass.class.getResourceAsStream ... Вы можете преобразовать свой поток в устройство записи с InputStreamReader, чем.

Обратите внимание, что в примере пропущен некоторый блок try-catch-finally.

1 голос
/ 23 декабря 2011

Две вещи для проверки

1.Проблемы с classpath

Убедитесь, что вы установили classpath пакета OSGi через MANIFEST.MF, чтобы включить точку:

Bundle-ClassPath: .

Точка означает включение корня пакета в класс- иерархия загрузки, где скорее всего находится ваша папка «speedtemplates».

И вам нужно иметь jar-файлы Velocity в том же пакете, где находятся ваши шаблоны-файлы, потому что в противном случае вы получите проблемы с загрузкой классов как Velocity.находился бы в другом пучке и, таким образом, вообще не видел бы «шаблонов скорости» в своем пути к классам.

2.Для ClasspathResourceLoader не существует «пути»

ClasspathResourceLoader не поддерживает установку «пути», поскольку он использует Classpath по определению, поэтому либо добавьте «speedtemplates» к Classpath в пакете OSGi (MANIFESt.MF)или ссылки на шаблоны скорости с полным путем, то есть "speedtemplates / index.vm"

0 голосов
/ 19 июня 2015

Через 2 дня я и его коллега нашли решение, которое Velocity Engine предлагает по умолчанию: file.resource.loader.class = org.apache.velocity.runtime.resource.loader.FileResourceLoader

Создан собственный классЗагрузчик ресурсов вот так

public static final class PdfResourceLoader extends ResourceLoader

@Override
public void init(ExtendedProperties configuration)
{
}

@Override
public InputStream getResourceStream(String source) throws ResourceNotFoundException
{
  return getClass().getResourceAsStream(source);
}

@Override
public boolean isSourceModified(Resource resource)
{
  return false;
}

@Override
public long getLastModified(Resource resource)
{
  return 0;
}
}

установил новый загрузчик классов контекста

Thread.currentThread().setContextClassLoader(PdfResourceLoader.class.getClassLoader());  
    VelocityEngine ve = new VelocityEngine();

изменил свойство по умолчанию внутри движка скоростей

ve.setProperty("resource.loader", "pdf"); 
ve.setProperty("pdf.resource.loader.class",
PdfResourceLoader.class.getName());
ve.init(); 

Пример шаблона имени пути

String pathTemplate = "/templates/yourTemplateName.html";      
Template t = ve.getTemplate(pathTemplate, "UTF-8"); 

Что это

0 голосов
/ 14 марта 2012

Я столкнулся с похожей проблемой с шаблонами на основе загрузчика классов, где я хотел указать другой корень.Я решил эту проблему, создав подкласс ClasspathResourceLoader.

package my.package;

import java.io.InputStream;
import org.apache.commons.collections.ExtendedProperties;
import org.apache.velocity.exception.ResourceNotFoundException;
import org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader;

public class PrefixedClasspathResourceLoader 
    extends ClasspathResourceLoader
{
    /** Prefix to be added to any names */
    private String prefix = "";

    @Override
    public void init(ExtendedProperties configuration) {
        prefix = configuration.getString("prefix","");
    }

    @Override
    public InputStream getResourceStream(String name)
            throws ResourceNotFoundException 
    {
        return super.getResourceStream(prefix+name);
    }
}

Со следующими свойствами, установленными

resource.loader=myloader
myloader.resource.loader.class=my.package.PrefixedClasspathResourceLoader
myloader.resource.loader.prefix=/velocitytemplates/

, если у вас есть шаблон с именем index.vm, скорость будетзагрузчик классов для поиска ресурса с именем "/velocitytemplates/index.vm"

...