Sync common code between configure.ac files
[xapian.git] / xapian-bindings / java / java.i
blobc70f99df3083f0de5da3e6f03227d2b0869ebeef
1 %module(directors="1") xapian
2 %{
3 /* java.i: SWIG interface file for the Java bindings
5 * Copyright (c) 2007,2009,2011,2012,2014,2016,2017,2018,2019 Olly Betts
6 * Copyright (c) 2012 Dan Colish
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of the
11 * License, or (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
21 * USA
25 // Insert code to automatically load the JNI library.
26 %pragma(java) jniclasscode=%{
27 static {
28 System.loadLibrary("xapian_jni");
32 // Use SWIG directors for Java wrappers.
33 #define XAPIAN_SWIG_DIRECTORS
35 %include ../xapian-head.i
37 // Rename function and method names to match Java conventions (e.g. from
38 // get_description() to getDescription()).
39 %rename("%(lctitle)s",%$isfunction) "";
41 // Fix up API methods which aren't split by '_' on word boundaries.
43 %rename("getTermPos") get_termpos;
44 %rename("getTermFreq") get_termfreq;
45 %rename("getTermWeight") get_termweight;
46 %rename("getDocCount") get_doccount;
47 %rename("getDocId") get_docid;
48 %rename("getDocLength") get_doclength;
49 %rename("getDocumentId") get_document_id;
50 %rename("positionListBegin") positionlist_begin;
51 %rename("positionListEnd") positionlist_end;
52 %rename("getValueNo") get_valueno;
53 %rename("termListCount") termlist_count;
54 %rename("termListBegin") termlist_begin;
55 %rename("termListEnd") termlist_end;
56 %rename("getFirstItem") get_firstitem;
57 %rename("getSumPart") get_sumpart;
58 %rename("getMaxPart") get_maxpart;
59 %rename("getSumExtra") get_sumextra;
60 %rename("getMaxExtra") get_maxextra;
61 %rename("postListBegin") postlist_begin;
62 %rename("postListEnd") postlist_end;
63 %rename("allTermsBegin") allterms_begin;
64 %rename("allTermsEnd") allterms_end;
65 %rename("getLastDocId") get_lastdocid;
66 %rename("getAvLength") get_avlength;
67 %rename("stopListBegin") stoplist_begin;
68 %rename("stopListEnd") stoplist_end;
69 %rename("getMSet") get_mset;
70 %rename("getESet") get_eset;
72 // Avoid collision with Object.clone
73 %rename("cloneWeight") clone;
75 // toString is more Java-esque and also matches what the old JNI bindings did.
76 %rename("toString") get_description() const;
78 // The old JNI bindings wrapped operator() as accept() for MatchDecider and
79 // ExpandDecider.
80 %rename("accept") Xapian::MatchDecider::operator();
81 %rename("accept") Xapian::ExpandDecider::operator();
83 // By default, valueno is wrapped as long and "(long, bool)" collides with
84 // some of SWIG/Java's machinery, so for now we wrap valueno as int to avoid
85 // this problem.
86 %apply int { Xapian::valueno };
88 %inline {
89 namespace Xapian {
91 // Wrap Xapian::version_string as Xapian.Version.String() as Java can't have
92 // functions outside a class and we don't want Xapian.Xapian.versionString()!
93 class Version {
94 private:
95 Version();
96 ~Version();
97 public:
98 static const char * String() { return Xapian::version_string(); }
99 static int Major() { return Xapian::major_version(); }
100 static int Minor() { return Xapian::minor_version(); }
101 static int Revision() { return Xapian::revision(); }
108 #include <xapian/iterator.h>
111 namespace Xapian {
113 %ignore version_string;
114 %ignore major_version;
115 %ignore minor_version;
116 %ignore revision;
118 // For compatibility with the original JNI wrappers.
119 %extend PostingIterator {
120 Xapian::docid next () {
121 Xapian::docid tmp;
122 if (Xapian::iterator_valid(*self)) {
123 tmp = (**self);
124 ++(*self);
125 } else {
126 tmp = -1;
128 return tmp;
131 bool hasNext() const { return Xapian::iterator_valid(*self); }
134 %extend TermIterator {
135 std::string next () {
136 std:string tmp;
137 if (Xapian::iterator_valid(*self)) {
138 tmp = (**self);
139 ++(*self);
141 return tmp;
144 bool hasNext() const { return Xapian::iterator_valid(*self); }
147 %extend ValueIterator {
148 std::string next () {
149 std:string tmp;
150 if (Xapian::iterator_valid(*self)) {
151 tmp = (**self);
152 ++(*self);
154 return tmp;
157 bool hasNext() const { return Xapian::iterator_valid(*self); }
160 %extend ESetIterator {
161 std::string next () {
162 std:string tmp;
163 if (Xapian::iterator_valid(*self)) {
164 tmp = (**self);
165 ++(*self);
167 return tmp;
170 bool hasNext() const { return Xapian::iterator_valid(*self); }
173 %extend MSetIterator {
174 Xapian::docid next () {
175 Xapian::docid tmp;
176 if (Xapian::iterator_valid(*self)) {
177 tmp = (**self);
178 ++(*self);
179 } else {
180 tmp = -1;
182 return tmp;
185 bool hasNext() const { return Xapian::iterator_valid(*self); }
190 #define XAPIAN_MIXED_SUBQUERIES_BY_ITERATOR_TYPEMAP
193 class XapianSWIGStrItor {
194 JNIEnv * jenv;
196 jobjectArray array;
198 jsize i;
200 public:
201 typedef std::random_access_iterator_tag iterator_category;
202 typedef Xapian::Query value_type;
203 typedef Xapian::termcount_diff difference_type;
204 typedef Xapian::Query * pointer;
205 typedef Xapian::Query & reference;
207 XapianSWIGStrItor() { }
209 void begin(JNIEnv * jenv_, jobjectArray array_) {
210 jenv = jenv_;
211 array = array_;
212 i = 0;
215 void end(jsize len_) {
216 i = len_;
219 XapianSWIGStrItor & operator++() {
220 ++i;
221 return *this;
224 Xapian::Query operator*() const {
225 jstring term = (jstring)jenv->GetObjectArrayElement(array, i);
226 const char *c_term = jenv->GetStringUTFChars(term, 0);
227 Xapian::Query subq(c_term);
228 jenv->ReleaseStringUTFChars(term, c_term);
229 jenv->DeleteLocalRef(term);
230 return subq;
233 bool operator==(const XapianSWIGStrItor & o) {
234 return i == o.i;
237 bool operator!=(const XapianSWIGStrItor & o) {
238 return !(*this == o);
241 difference_type operator-(const XapianSWIGStrItor &o) const {
242 return i - o.i;
246 class XapianSWIGQueryItor {
247 jlong * p;
249 public:
250 typedef std::random_access_iterator_tag iterator_category;
251 typedef Xapian::Query value_type;
252 typedef Xapian::termcount_diff difference_type;
253 typedef Xapian::Query * pointer;
254 typedef Xapian::Query & reference;
256 XapianSWIGQueryItor() { }
258 void set_p(jlong * p_) { p = p_; }
260 XapianSWIGQueryItor & operator++() {
261 ++p;
262 return *this;
265 const Xapian::Query & operator*() const {
266 return **(Xapian::Query **)p;
269 bool operator==(const XapianSWIGQueryItor & o) {
270 return p == o.p;
273 bool operator!=(const XapianSWIGQueryItor & o) {
274 return !(*this == o);
277 difference_type operator-(const XapianSWIGQueryItor &o) const {
278 return p - o.p;
284 %typemap(in) (XapianSWIGStrItor qbegin, XapianSWIGStrItor qend) {
285 $1.begin(jenv, $input);
286 $2.end(jenv->GetArrayLength($input));
289 /* These 3 typemaps tell SWIG what JNI and Java types to use. */
290 %typemap(jni) XapianSWIGStrItor, XapianSWIGStrItor "jobjectArray"
291 %typemap(jtype) XapianSWIGStrItor, XapianSWIGStrItor "String[]"
292 %typemap(jstype) XapianSWIGStrItor, XapianSWIGStrItor "String[]"
294 /* This typemap handles the conversion of the jtype to jstype typemap type
295 * and vice versa. */
296 %typemap(javain) XapianSWIGStrItor, XapianSWIGStrItor "$javainput"
298 %typemap(in) (XapianSWIGQueryItor qbegin, XapianSWIGQueryItor qend) %{
299 if (!$input)
300 SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null array");
301 jlong * jarr = jenv->GetLongArrayElements($input, NULL);
302 if (!jarr) return $null;
303 $1.set_p(jarr);
304 $2.set_p(jarr + jenv->GetArrayLength($input));
307 %typemap(freearg) (XapianSWIGQueryItor qbegin, XapianSWIGQueryItor qend) %{
308 /* We don't change the array so use JNI_ABORT to avoid any work
309 * copying back non-existent changes if the JVM gave us a copy
310 * of the array data. */
311 jenv->ReleaseLongArrayElements($input, jarr, JNI_ABORT);
314 /* These 3 typemaps tell SWIG what JNI and Java types to use. */
315 %typemap(jni) XapianSWIGQueryItor, XapianSWIGQueryItor "jlongArray"
316 %typemap(jtype) XapianSWIGQueryItor, XapianSWIGQueryItor "long[]"
317 %typemap(jstype) XapianSWIGQueryItor, XapianSWIGQueryItor "Query[]"
319 /* This typemap handles the conversion of the jstype to the jtype. */
320 %typemap(javain) XapianSWIGQueryItor, XapianSWIGQueryItor "Query.cArrayUnwrap($javainput)"
322 %typemap(javacode) Xapian::Query %{
323 // For compatibility with the original JNI wrappers.
324 public final static op OP_AND = op.OP_AND;
325 public final static op OP_OR = op.OP_OR;
326 public final static op OP_AND_NOT = op.OP_AND_NOT;
327 public final static op OP_XOR = op.OP_XOR;
328 public final static op OP_AND_MAYBE = op.OP_AND_MAYBE;
329 public final static op OP_FILTER = op.OP_FILTER;
330 public final static op OP_NEAR = op.OP_NEAR;
331 public final static op OP_PHRASE = op.OP_PHRASE;
332 public final static op OP_ELITE_SET = op.OP_ELITE_SET;
333 public final static op OP_VALUE_RANGE = op.OP_VALUE_RANGE;
335 public final static Query MatchAll = new Query("");
336 public final static Query MatchNothing = new Query();
338 protected static long[] cArrayUnwrap(Query[] arrayWrapper) {
339 long[] cArray = new long[arrayWrapper.length];
340 for (int i=0; i<arrayWrapper.length; i++)
341 cArray[i] = Query.getCPtr(arrayWrapper[i]);
342 return cArray;
346 #define XAPIAN_TERMITERATOR_PAIR_OUTPUT_TYPEMAP
347 %typemap(out) std::pair<Xapian::TermIterator, Xapian::TermIterator> {
348 jobjectArray c_result;
349 jboolean jbool;
350 jstring temp_string;
351 int n = 0;
352 const jclass clazz = jenv->FindClass("java/lang/String");
353 const jclass arrayClass = jenv->FindClass("java/util/ArrayList");
354 if (arrayClass == NULL)
355 return NULL;
357 const jmethodID mid_init = jenv->GetMethodID(arrayClass, "<init>", "()V");
358 if (mid_init == NULL)
359 return NULL;
361 jobject objArr = jenv->NewObject(arrayClass, mid_init);
362 if (objArr == NULL)
363 return NULL;
365 const jmethodID mid_add = jenv->GetMethodID(arrayClass, "add",
366 "(Ljava/lang/Object;)Z");
367 if (mid_add == NULL)
368 return NULL;
370 const jmethodID mid_toArray = jenv->GetMethodID(arrayClass, "toArray", "([Ljava/lang/Object;)[Ljava/lang/Object;");
371 if (mid_toArray == NULL) return NULL;
373 for (Xapian::TermIterator i = $1.first; i != $1.second; ++i) {
374 temp_string = jenv->NewStringUTF((*i).c_str());
375 jbool = jenv->CallBooleanMethod(objArr, mid_add, temp_string);
376 if (jbool == false) return NULL;
377 jenv->DeleteLocalRef(temp_string);
378 ++n;
381 c_result = jenv->NewObjectArray(n, clazz, NULL);
382 $result = (jobjectArray)jenv->CallObjectMethod(objArr, mid_toArray, c_result);
385 %typemap(jni) std::pair<Xapian::TermIterator, Xapian::TermIterator> "jobjectArray"
386 %typemap(jtype) std::pair<Xapian::TermIterator, Xapian::TermIterator> "String[]"
387 %typemap(jstype) std::pair<Xapian::TermIterator, Xapian::TermIterator> "String[]"
389 /* This typemap handles the conversion of the jstype to the jtype. */
390 %typemap(javaout) std::pair<Xapian::TermIterator, Xapian::TermIterator> { return $jnicall; }
392 // Typemaps for converting C++ std::string to/from Java byte[] for cases
393 // where the C++ API uses it for binary data.
395 // Terms, document data and user metadata can also be binary data, but for at
396 // least for now we won't worry about that.
398 %typemap(in) const binary_std_string & (jbyte * jarr, std::string c_arg) %{
399 if (!$input)
400 SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null array");
401 jarr = jenv->GetByteArrayElements($input, NULL);
402 if (!jarr) return $null;
403 c_arg.assign(reinterpret_cast<char*>(jarr), jenv->GetArrayLength($input));
404 jenv->ReleaseByteArrayElements($input, jarr, JNI_ABORT);
405 $1 = &c_arg;
408 %typemap(out) binary_std_string {
409 size_t len = $1.size();
410 jbyteArray c_result = jenv->NewByteArray(len);
411 const jbyte* data = reinterpret_cast<const jbyte*>($1.data());
412 // Final parameter was not const in Java 6 and earlier.
413 jbyte* data_nc = const_cast<jbyte*>(data);
414 jenv->SetByteArrayRegion(c_result, 0, len, data_nc);
415 $result = c_result;
418 %typemap(directorin, descriptor="B[", noblock=1) const binary_std_string & {
419 size_t $1_len = $1.size();
420 $input = jenv->NewByteArray($1_len);
421 Swig::LocalRefGuard $1_refguard(jenv, $input);
423 const jbyte* data = reinterpret_cast<const jbyte*>($1.data());
424 // Final parameter was not const in Java 6 and earlier.
425 jbyte* data_nc = const_cast<jbyte*>(data);
426 jenv->SetByteArrayRegion($input, 0, $1_len, data_nc);
430 %typemap(jni) binary_std_string, const binary_std_string & "jbyteArray"
431 %typemap(jtype) binary_std_string, const binary_std_string & "byte[]"
432 %typemap(jstype) binary_std_string, const binary_std_string & "byte[]"
434 %inline %{
435 typedef std::string binary_std_string;
438 %apply const binary_std_string & { const std::string & range_limit };
439 %apply const binary_std_string & { const std::string & range_lower };
440 %apply const binary_std_string & { const std::string & range_upper };
441 %apply const binary_std_string & { const std::string & serialised };
442 %apply const binary_std_string & { const std::string & value };
444 %apply binary_std_string { std::string serialise() };
445 %apply binary_std_string { std::string get_value() };
446 %apply binary_std_string { std::string get_value_lower_bound() };
447 %apply binary_std_string { std::string get_value_upper_bound() };
448 %apply binary_std_string { std::string Xapian::ValueIterator::operator*() };
449 %apply binary_std_string { std::string Xapian::sortable_serialise(double) };
451 #pragma SWIG nowarn=822 /* Suppress warning about covariant return types (FIXME - check if this is a problem!) */
453 // For QueryParser::add_boolean_prefix() and add_rangeprocessor().
454 %typemap(jni) const std::string* "char*"
455 %typemap(jtype) const std::string* "String"
456 %typemap(jstype) const std::string* "String"
458 %typemap(in) const std::string* %{
459 $*1_ltype $1_str;
460 if ($input) {
461 $1_str.assign($input);
462 $1 = &$1_str;
463 } else {
464 $1 = nullptr;
468 %typemap(javain) const std::string* "$javainput"
470 %typecheck(SWIG_TYPECHECK_STRING) const std::string* ""
472 %include ../generic/except.i
473 %include ../xapian-headers.i
474 %include ../fake_dbfactory.i
476 // Compatibility wrapping for Xapian::BAD_VALUENO (wrapped as a constant since
477 // xapian-bindings 1.4.10).
478 %rename("getBAD_VALUENO") getBAD_VALUENO;
479 %inline %{
480 namespace Xapian {
481 static Xapian::valueno getBAD_VALUENO() { return Xapian::BAD_VALUENO; }
484 // Can't throw an exception.
485 %exception Xapian::getBAD_VALUENO "$action"