2013-10-15 3 views
0

Я пытаюсь настроить OpenNLP NameFinder в проекте с дескриптором генератора функций XML и некоторыми нестандартными функциями. Дескриптор XML поддерживает пользовательские функции генераторов:Использование генераторов настраиваемых функций с параметрами в OpenNLP

<generators> 
    <cache> 
    <generators> 
     ... 
     <custom class="com.example.MyFeatureGenerator"/> 
    </cache> 
</generators> 

Однако, документация не говорит о передаче параметров генератора функций. Создание нового класса для каждой немного другой конфигурации генератора функций нежелательно. С другой стороны, создание генераторов функций программно, вероятно, означает дублирование большей части кода OpenNLP для обработки установки генератора функций. Каков рекомендуемый способ использования генераторов настраиваемых функций в OpenNLP?

ответ

0

Нет правильного решения, но я работал над проблемой, зарегистрировав новую фабрику функций в OpenNLP. К сожалению, для этого требуется доступ к частным частям класса OpenNLP GeneratorFactory через отражение. Вот рабочее решение.

Во-первых, определить новый класс, названный XmlDescriptorUtil:

import java.lang.reflect.Field; 
import java.lang.reflect.InvocationHandler; 
import java.lang.reflect.Method; 
import java.lang.reflect.Proxy; 
import java.util.Map; 

import opennlp.tools.util.InvalidFormatException; 
import opennlp.tools.util.featuregen.AdaptiveFeatureGenerator; 
import opennlp.tools.util.featuregen.FeatureGeneratorResourceProvider; 
import opennlp.tools.util.featuregen.GeneratorFactory; 

import org.w3c.dom.Element; 

public final class XmlDescriptorUtil { 
    private XmlDescriptorUtil(){}; 

    public static abstract class XmlDescriptorFactory implements InvocationHandler 
    { 
    @Override 
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 
     return create((Element)args[0], (FeatureGeneratorResourceProvider)args[1]); 
    } 

    public abstract AdaptiveFeatureGenerator create(Element generatorElement, FeatureGeneratorResourceProvider resourceManager) 
     throws InvalidFormatException; 
    } 

    public static void register(String name, XmlDescriptorFactory factory) throws Exception 
    { 
    Class<?> factoryInterface = Class.forName(GeneratorFactory.class.getName()+"$XmlFeatureGeneratorFactory"); 
    Object proxy = Proxy.newProxyInstance(GeneratorFactory.class.getClassLoader(), new Class[]{factoryInterface}, factory); 
    registerByProxy(name, proxy); 
    } 

    private static void registerByProxy(String name, Object proxy) throws Exception 
    { 
    Field f = GeneratorFactory.class.getDeclaredField("factories"); 
    f.setAccessible(true); 
    @SuppressWarnings("unchecked") 
    Map<String, Object> factories = (Map<String, Object>) f.get(null); 
    factories.put(name, proxy); 
    } 

} 

Затем создать генератор особенность завод, который реализует открытый интерфейс XmlDescriptorUtil$XmlDescriptorFactory:

public static void main(String[] args) { 
    XmlDescriptorUtil.register("myCustom", new XmlDescriptorUtil.XmlDescriptorFactory() { 
    @Override 
    public AdaptiveFeatureGenerator create(Element generatorElement, FeatureGeneratorResourceProvider resourceManager) throws InvalidFormatException { 
     return new MyFeatureGenerator(); 
    }); 
} 

Теперь генератор функция готова к использовать и может использоваться в дескрипторе XML:

<generators> 
    <cache> 
    <generators> 
     ... 
     <myCustom/> 
    </generators> 
    </cache> 
</generators> 

Если генератору функций нужны параметры, их можно извлечь из generatorElement в заводском классе.

0

Если вы не возражаете открыть проблему с jira на Apache OpenNLP и попросите исправить это. Пользовательский элемент должен иметь возможность передавать параметры и внешние ресурсы.

+0

Больше комментариев, чем ответ – DaveHogan

+2

Потому что это невозможно комментировать, когда вы новый пользователь; не так ли? – wau

Смежные вопросы