在OpenNLP中使用带参数的自定义特征生成器

在OpenNLP中使用带参数的自定义特征生成器,opennlp,Opennlp,我试图在一个项目中使用XML特性生成器描述符和一些非标准特性设置OpenNLP NameFinder。XML描述符支持自定义功能生成器: <generators> <cache> <generators> ... <custom class="com.example.MyFeatureGenerator"/> </cache> </generators> ... 但是,文档

我试图在一个项目中使用XML特性生成器描述符和一些非标准特性设置OpenNLP NameFinder。XML描述符支持自定义功能生成器:

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

...


但是,文档并没有提到将参数传递给特征生成器。不希望为特征生成器的每个稍有不同的配置创建一个新类。另一方面,以编程方式创建特性生成器可能意味着复制大部分OpenNLP代码来处理特性生成器设置。在OpenNLP中使用自定义功能生成器的推荐方法是什么?

目前还没有合适的解决方案,但我通过在OpenNLP中注册一个新的功能工厂解决了这个问题。不幸的是,这需要通过反射访问OpenNLP类的私有部分。这里有一个有效的解决方案

首先,定义一个新类,名为
XMLDescriptorRutil

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);
  }

}
现在,功能生成器已准备就绪,可以在XML描述符中使用:

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

...

如果feature generator需要参数,可以从factory类中的
generatorElement
中提取参数。

如果您不介意在Apache OpenNLP上打开jira问题并请求修复此问题。自定义元素应该可以传入参数和外部资源。

更多的是注释而不是应答,因为当您是新用户时,不可能进行注释;不是吗?
<generators>
  <cache>
    <generators>
      ...
      <myCustom/>
    </generators>
  </cache> 
</generators>