Lucene代码分析8
今天继续对Lucene中的Analysis进行分析
阅读的DotLucene版本是1.9.RC1
PyLucene基本工作原理
首先必须了解 PyLucene是如何实现的,其实 PyLucene 是在 Python 程序中嵌入了一个 JVM 来使用 Lucene,这个工作主要通过 JCC 来完成,JCC 编译 Lucene 源码为 C++,然后在 Python 中通过 JNI 进行调用。
现在我们希望在 Python 中扩展 Java 源码中的类,仍然要借助 JCC。
添加 Java 源码
假设我们要扩展 Lucene 中的类 A,首先要用 Java 写一个子类 PythonA 继承自 A,通常放在 org.apache.pylucene 里。示例代码如下:
package org.apache.pylucene.analysis;
import java.io.Reader;
import org.apache.lucene.analysis.Analyzer;
public class PythonAnalyzer extends Analyzer {
private long pythonObject;
public PythonAnalyzer()
{
}
public void pythonExtension(long pythonObject)
{
this.pythonObject = pythonObject;
}
public long pythonExtension()
{
return this.pythonObject;
}
public void finalize()
throws Throwable
{
pythonDecRef();
}
public native void pythonDecRef();
/*————————————————————分割线———————————————————————————*/
@Override
public native TokenStreamComponents createComponents(final String fieldName);
@Override
public native Reader initReader(String fieldName, Reader reader);
}
分割线以上除了构造函数以外不管扩展哪个类都必须这样写,分割线以下根据自己的需求来就好。方法最好用 public 来修饰,用 protected 可能会出错。
写好以后放到可以被 make 到的地方,当然最好放在 org.apache.pylucene 中,然后重新 make、make install。
在 Python 中扩展及遇到的问题
完成上面步骤后,在 Python 中直接继承 PythonA 就行,注意如果有 __init__() 的话,必须调用父类的构造方法。
遇到的问题:
1、Java 中 .class 的用法显然在 Python 中无法使用,而 getClass() 方法是通过对象来调用而不是类,可以考虑 Class.forName(),但是 Lucene 源码中的类使用 Class.forName() 可能找不到,最好使用 findClass() 方法。
>>> import lucene
>>> from lucene import findClass
>>> lucene.initVM(vmargs=['-Djava.awt.headless=true'])
>>> findClass('org/apache/lucene/document/Document')
<Class: class org.apache.lucene.document.Document>
>>> Class.forName('org.apache.lucene.document.Document')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
lucene.JavaError: java.lang.ClassNotFoundException: org/apache/lucene/document/Document
>>> Class.forName('java.lang.Object')
<Class: class java.lang.Object>
2、Java源码中的父类 A 的变量在 Python 的子类中无法访问,可以在PythonA 的代码中添加 相应的 get 方法,提供访问接口。
3、关于处理 Java 中的数组,在 Python 中可以通过如下方式构造 Java 中的数组:
>>> array = JArray('int')(size)
# the resulting Java int array is initialized with zeroes
>>> array = JArray('int')(sequence)
# the sequence must only contain ints
# the resulting Java int array contains the ints in the sequence
要把一个 Java 中的 char 数组转换为 Python 中的 str,只需要执行
''.join(array)
在 Python 中访问的话支持使用 [] 进行访问,可以修改元素内容,但无法改变数组大小。
4、Unicode 对象 s 转为 utf-8 :
s.encode('utf-8')
上一篇: lucene代码分析