2013-10-15 12 views
0

我嘗試在具有XML要素生成器描述符和一些非標準要素的項目中設置OpenNLP NameFinder。 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

如果您不介意在Apache OpenNLP上打開jira問題並請求解決此問題。自定義元素應該可以傳入參數和外部資源。

+0

更多的評論比回答 – DaveHogan

+2

因爲當你是新用戶時不可能評論;是不是這樣? – wau

相關問題