diff --git a/android-kiwix-lib-publisher/kiwixLibAndroid/src/main/AndroidManifest.xml b/android-kiwix-lib-publisher/kiwixLibAndroid/src/main/AndroidManifest.xml
index b32776b..e9b809a 100644
--- a/android-kiwix-lib-publisher/kiwixLibAndroid/src/main/AndroidManifest.xml
+++ b/android-kiwix-lib-publisher/kiwixLibAndroid/src/main/AndroidManifest.xml
@@ -1,5 +1,5 @@
+ package="org.kiwix.kiwixlib">
+
+
+
+
+
+
diff --git a/src/wrapper/java/book.cpp b/src/wrapper/java/book.cpp
new file mode 100644
index 0000000..b76492c
--- /dev/null
+++ b/src/wrapper/java/book.cpp
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2020 Matthieu Gautier
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+
+#include
+#include "org_kiwix_kiwixlib_Book.h"
+
+#include "utils.h"
+#include "book.h"
+
+JNIEXPORT void JNICALL
+Java_org_kiwix_kiwixlib_Book_allocate(
+ JNIEnv* env, jobject thisObj)
+{
+ allocate(env, thisObj);
+}
+
+JNIEXPORT void JNICALL
+Java_org_kiwix_kiwixlib_Book_dispose(JNIEnv* env, jobject thisObj)
+{
+ dispose(env, thisObj);
+}
+
+#define BOOK (getPtr(env, thisObj))
+
+#define GETTER(retType, name) JNIEXPORT retType JNICALL \
+Java_org_kiwix_kiwixlib_Book_##name (JNIEnv* env, jobject thisObj) \
+{ \
+ auto cRet = BOOK->name(); \
+ retType ret = c2jni(cRet, env); \
+ return ret; \
+}
+
+GETTER(jstring, getId)
+GETTER(jstring, getPath)
+GETTER(jboolean, isPathValid)
+GETTER(jstring, getTitle)
+GETTER(jstring, getDescription)
+GETTER(jstring, getLanguage)
+GETTER(jstring, getCreator)
+GETTER(jstring, getPublisher)
+GETTER(jstring, getDate)
+GETTER(jstring, getUrl)
+GETTER(jstring, getName)
+GETTER(jstring, getTags)
+GETTER(jlong, getArticleCount)
+GETTER(jlong, getMediaCount)
+GETTER(jlong, getSize)
+GETTER(jstring, getFavicon)
+GETTER(jstring, getFaviconUrl)
+GETTER(jstring, getFaviconMimeType)
+
+#undef GETTER
diff --git a/src/wrapper/java/filter.cpp b/src/wrapper/java/filter.cpp
new file mode 100644
index 0000000..09c0734
--- /dev/null
+++ b/src/wrapper/java/filter.cpp
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2019-2020 Matthieu Gautier
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+
+#include
+#include "org_kiwix_kiwixlib_Filter.h"
+
+#include "library.h"
+#include "utils.h"
+
+/* Kiwix Reader JNI functions */
+METHOD0(void, Filter, allocate) {
+ allocate(env, thisObj);
+}
+
+METHOD0(void, Filter, dispose) {
+ dispose(env, thisObj);
+}
+
+#define FILTER (getPtr(env, thisObj))
+
+#define FORWARD(name, args_type) \
+METHOD(jobject, Filter, name, args_type value) { \
+ FILTER->name(jni2c(value, env)); \
+ return thisObj; \
+}
+
+#define FORWARDA(name, args_type) \
+METHOD(jobject, Filter, name, jobjectArray value) { \
+ FILTER->name(jni2c(value, env)); \
+ return thisObj; \
+}
+
+
+
+FORWARD(local, jboolean)
+FORWARD(remote, jboolean)
+FORWARD(valid, jboolean)
+FORWARDA(acceptTags, jstring)
+FORWARDA(rejectTags, jstring)
+FORWARD(lang, jstring)
+FORWARD(publisher, jstring)
+FORWARD(creator, jstring)
+FORWARD(maxSize, jlong)
+FORWARD(query, jstring)
+
+
diff --git a/src/wrapper/java/kiwixicu.cpp b/src/wrapper/java/kiwixicu.cpp
new file mode 100644
index 0000000..0c604eb
--- /dev/null
+++ b/src/wrapper/java/kiwixicu.cpp
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2013 Emmanuel Engelhart
+ * Copyright (C) 2017 Matthieu Gautier
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#include
+#include "org_kiwix_kiwixlib_JNIICU.h"
+
+#include
+#include
+
+#include "unicode/putil.h"
+
+#include "utils.h"
+
+#if __ANDROID__
+pthread_mutex_t globalLock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER;
+#else
+pthread_mutex_t globalLock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
+#endif
+
+JNIEXPORT void JNICALL Java_org_kiwix_kiwixlib_JNIICU_setDataDirectory(
+ JNIEnv* env, jclass kclass, jstring dirStr)
+{
+ std::string cPath = jni2c(dirStr, env);
+
+ Lock l;
+ try {
+ u_setDataDirectory(cPath.c_str());
+ } catch (...) {
+ std::cerr << "Unable to set data directory " << cPath << std::endl;
+ }
+}
diff --git a/src/wrapper/java/kiwixreader.cpp b/src/wrapper/java/kiwixreader.cpp
new file mode 100644
index 0000000..7bc61eb
--- /dev/null
+++ b/src/wrapper/java/kiwixreader.cpp
@@ -0,0 +1,473 @@
+/*
+ * Copyright (C) 2013 Emmanuel Engelhart
+ * Copyright (C) 2017 Matthieu Gautier
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+
+#include
+#include
+#include "org_kiwix_kiwixlib_JNIKiwixReader.h"
+
+#include "tools/base64.h"
+#include "reader.h"
+#include "utils.h"
+
+/* Kiwix Reader JNI functions */
+JNIEXPORT jlong JNICALL Java_org_kiwix_kiwixlib_JNIKiwixReader_getNativeReader(
+ JNIEnv* env, jobject obj, jstring filename)
+{
+ std::string cPath = jni2c(filename, env);
+
+ LOG("Attempting to create reader with: %s", cPath.c_str());
+ Lock l;
+ try {
+ kiwix::Reader* reader = new kiwix::Reader(cPath);
+ return reinterpret_cast(new Handle(reader));
+ } catch (std::exception& e) {
+ LOG("Error opening ZIM file");
+ LOG(e.what());
+ return 0;
+ }
+}
+
+JNIEXPORT void JNICALL
+Java_org_kiwix_kiwixlib_JNIKiwixReader_dispose(JNIEnv* env, jobject obj)
+{
+ Handle::dispose(env, obj);
+}
+
+#define READER (Handle::getHandle(env, obj))
+
+/* Kiwix library functions */
+JNIEXPORT jstring JNICALL
+Java_org_kiwix_kiwixlib_JNIKiwixReader_getMainPage(JNIEnv* env, jobject obj)
+{
+ jstring url;
+
+ try {
+ std::string cUrl = READER->getMainPage().getPath();
+ url = c2jni(cUrl, env);
+ } catch (std::exception& e) {
+ LOG("Unable to get ZIM main page");
+ LOG(e.what());
+ url = NULL;
+ }
+ return url;
+}
+
+JNIEXPORT jstring JNICALL
+Java_org_kiwix_kiwixlib_JNIKiwixReader_getId(JNIEnv* env, jobject obj)
+{
+ jstring id;
+
+ try {
+ std::string cId = READER->getId();
+ id = c2jni(cId, env);
+ } catch (std::exception& e) {
+ LOG("Unable to get ZIM id");
+ LOG(e.what());
+ id = NULL;
+ }
+
+ return id;
+}
+
+JNIEXPORT jint JNICALL
+Java_org_kiwix_kiwixlib_JNIKiwixReader_getFileSize(JNIEnv* env, jobject obj)
+{
+ jint size = 0;
+
+ try {
+ int cSize = READER->getFileSize();
+ size = c2jni(cSize, env);
+ } catch (std::exception& e) {
+ LOG("Unable to get ZIM file size");
+ LOG(e.what());
+ }
+
+ return size;
+}
+
+JNIEXPORT jstring JNICALL
+Java_org_kiwix_kiwixlib_JNIKiwixReader_getCreator(JNIEnv* env, jobject obj)
+{
+ jstring creator;
+
+ try {
+ std::string cCreator = READER->getCreator();
+ creator = c2jni(cCreator, env);
+ } catch (std::exception& e) {
+ LOG("Unable to get ZIM creator");
+ LOG(e.what());
+ creator = NULL;
+ }
+
+ return creator;
+}
+
+JNIEXPORT jstring JNICALL
+Java_org_kiwix_kiwixlib_JNIKiwixReader_getPublisher(JNIEnv* env, jobject obj)
+{
+ jstring publisher;
+
+ try {
+ std::string cPublisher = READER->getPublisher();
+ publisher = c2jni(cPublisher, env);
+ } catch (std::exception& e) {
+ LOG("Unable to get ZIM publish");
+ LOG(e.what());
+ publisher = NULL;
+ }
+ return publisher;
+}
+
+JNIEXPORT jstring JNICALL
+Java_org_kiwix_kiwixlib_JNIKiwixReader_getName(JNIEnv* env, jobject obj)
+{
+ jstring name;
+
+ try {
+ std::string cName = READER->getName();
+ name = c2jni(cName, env);
+ } catch (std::exception& e) {
+ LOG("Unable to get ZIM name");
+ LOG(e.what());
+ name = NULL;
+ }
+ return name;
+}
+
+JNIEXPORT jstring JNICALL
+Java_org_kiwix_kiwixlib_JNIKiwixReader_getFavicon(JNIEnv* env, jobject obj)
+{
+ jstring favicon;
+
+ try {
+ std::string cContent;
+ std::string cMime;
+ READER->getFavicon(cContent, cMime);
+ favicon = c2jni(
+ base64_encode(cContent),
+ env);
+ } catch (std::exception& e) {
+ LOG("Unable to get ZIM favicon");
+ LOG(e.what());
+ favicon = NULL;
+ }
+ return favicon;
+}
+
+JNIEXPORT jstring JNICALL
+Java_org_kiwix_kiwixlib_JNIKiwixReader_getDate(JNIEnv* env, jobject obj)
+{
+ jstring date;
+
+ try {
+ std::string cDate = READER->getDate();
+ date = c2jni(cDate, env);
+ } catch (std::exception& e) {
+ LOG("Unable to get ZIM date");
+ LOG(e.what());
+ date = NULL;
+ }
+ return date;
+}
+
+JNIEXPORT jstring JNICALL
+Java_org_kiwix_kiwixlib_JNIKiwixReader_getLanguage(JNIEnv* env, jobject obj)
+{
+ jstring language;
+
+ try {
+ std::string cLanguage = READER->getLanguage();
+ language = c2jni(cLanguage, env);
+ } catch (std::exception& e) {
+ LOG("Unable to get ZIM language");
+ LOG(e.what());
+ language = NULL;
+ }
+
+ return language;
+}
+
+JNIEXPORT jstring JNICALL Java_org_kiwix_kiwixlib_JNIKiwixReader_getMimeType(
+ JNIEnv* env, jobject obj, jstring url)
+{
+ jstring mimeType;
+
+ std::string cUrl = jni2c(url, env);
+ try {
+ auto entry = READER->getEntryFromEncodedPath(cUrl);
+ auto cMimeType = entry.getMimetype();
+ mimeType = c2jni(cMimeType, env);
+ } catch (std::exception& e) {
+ LOG("Unable to get mime-type for url: %s", cUrl.c_str());
+ LOG(e.what());
+ mimeType = NULL;
+ }
+ return mimeType;
+}
+
+JNIEXPORT jstring JNICALL Java_org_kiwix_kiwixlib_JNIKiwixReader_checkUrl(
+ JNIEnv* env, jobject obj, jstring url)
+{
+ jstring finalUrl;
+ std::string cUrl = jni2c(url, env);
+ try {
+ auto entry = READER->getEntryFromEncodedPath(cUrl);
+ entry = entry.getFinalEntry();
+ finalUrl = c2jni(entry.getPath(), env);
+ } catch (std::exception& e) {
+ finalUrl = c2jni(std::string(), env);
+ }
+ return finalUrl;
+}
+
+JNIEXPORT jbyteArray JNICALL Java_org_kiwix_kiwixlib_JNIKiwixReader_getContent(
+ JNIEnv* env, jobject obj, jobject url, jobject titleObj, jobject mimeTypeObj, jobject sizeObj)
+{
+ /* Default values */
+ setStringObjValue("", titleObj, env);
+ setStringObjValue("", mimeTypeObj, env);
+ setIntObjValue(0, sizeObj, env);
+ jbyteArray data = env->NewByteArray(0);
+
+ /* Retrieve the content */
+ std::string cUrl = getStringObjValue(url, env);
+ unsigned int cSize = 0;
+
+ try {
+ auto entry = READER->getEntryFromEncodedPath(cUrl);
+ bool isRedirect = entry.isRedirect();
+ entry = entry.getFinalEntry();
+ cSize = entry.getSize();
+ setIntObjValue(cSize, sizeObj, env);
+ setStringObjValue(entry.getMimetype(), mimeTypeObj, env);
+ setStringObjValue(entry.getTitle(), titleObj, env);
+ if (isRedirect) {
+ setStringObjValue(entry.getPath(), url, env);
+ } else {
+ data = env->NewByteArray(cSize);
+ env->SetByteArrayRegion(
+ data, 0, cSize, reinterpret_cast(entry.getBlob().data()));
+ }
+ } catch (std::exception& e) {
+ LOG("Unable to get content for url: %s", cUrl.c_str());
+ LOG(e.what());
+ }
+
+ return data;
+}
+
+JNIEXPORT jbyteArray JNICALL Java_org_kiwix_kiwixlib_JNIKiwixReader_getContentPart(
+ JNIEnv* env, jobject obj, jstring url, jint offset, jint len, jobject sizeObj)
+{
+ jbyteArray data = env->NewByteArray(0);
+ setIntObjValue(0, sizeObj, env);
+
+ /* Default values */
+ /* Retrieve the content */
+ std::string cUrl = jni2c(url, env);
+ unsigned int cOffset = jni2c(offset, env);
+ unsigned int cLen = jni2c(len, env);
+ try {
+ auto entry = READER->getEntryFromEncodedPath(cUrl);
+ entry = entry.getFinalEntry();
+
+ if (cLen == 0) {
+ setIntObjValue(entry.getSize(), sizeObj, env);
+ } else if (cOffset+cLen < entry.getSize()) {
+ auto blob = entry.getBlob(cOffset, cLen);
+ data = env->NewByteArray(cLen);
+ env->SetByteArrayRegion(
+ data, 0, cLen, reinterpret_cast(blob.data()));
+ setIntObjValue(cLen, sizeObj, env);
+ }
+ } catch (std::exception& e) {
+ LOG("Unable to get partial content for url: %s (%u : %u)", cUrl.c_str(), cOffset, cLen);
+ LOG(e.what());
+ }
+ return data;
+}
+
+JNIEXPORT jobject JNICALL
+Java_org_kiwix_kiwixlib_JNIKiwixReader_getDirectAccessInformation(
+ JNIEnv* env, jobject obj, jstring url)
+{
+ jclass classPair = env->FindClass("org/kiwix/kiwixlib/Pair");
+ jmethodID midPairinit = env->GetMethodID(classPair, "", "()V");
+ jobject pair = env->NewObject(classPair, midPairinit);
+ setPairObjValue("", 0, pair, env);
+
+ std::string cUrl = jni2c(url, env);
+ try {
+ auto entry = READER->getEntryFromEncodedPath(cUrl);
+ entry = entry.getFinalEntry();
+ auto part_info = entry.getDirectAccessInfo();
+ setPairObjValue(part_info.first, part_info.second, pair, env);
+ } catch (std::exception& e) {
+ LOG("Unable to get direct access info for url: %s", cUrl.c_str());
+ LOG(e.what());
+ }
+ return pair;
+}
+
+JNIEXPORT jboolean JNICALL
+Java_org_kiwix_kiwixlib_JNIKiwixReader_searchSuggestions(JNIEnv* env,
+ jobject obj,
+ jstring prefix,
+ jint count)
+{
+ jboolean retVal = JNI_FALSE;
+ std::string cPrefix = jni2c(prefix, env);
+ unsigned int cCount = jni2c(count, env);
+
+ try {
+ if (READER->searchSuggestionsSmart(cPrefix, cCount)) {
+ retVal = JNI_TRUE;
+ }
+ } catch (std::exception& e) {
+ LOG("Unable to get search results for pattern: %s", cPrefix.c_str());
+ LOG(e.what());
+ }
+
+ return retVal;
+}
+
+JNIEXPORT jboolean JNICALL
+Java_org_kiwix_kiwixlib_JNIKiwixReader_getNextSuggestion(JNIEnv* env,
+ jobject obj,
+ jobject titleObj,
+ jobject urlObj)
+{
+ jboolean retVal = JNI_FALSE;
+ std::string cTitle;
+ std::string cUrl;
+
+ try {
+ if (READER->getNextSuggestion(cTitle, cUrl)) {
+ setStringObjValue(cTitle, titleObj, env);
+ setStringObjValue(cUrl, urlObj, env);
+ retVal = JNI_TRUE;
+ }
+ } catch (std::exception& e) {
+ LOG("Unable to get next suggestion");
+ LOG(e.what());
+ }
+
+ return retVal;
+}
+
+JNIEXPORT jboolean JNICALL
+Java_org_kiwix_kiwixlib_JNIKiwixReader_getPageUrlFromTitle(JNIEnv* env,
+ jobject obj,
+ jstring title,
+ jobject urlObj)
+{
+ std::string cTitle = jni2c(title, env);
+
+ try {
+ auto entry = READER->getEntryFromTitle(cTitle);
+ entry = entry.getFinalEntry();
+ setStringObjValue(entry.getPath(), urlObj, env);
+ return JNI_TRUE;
+ } catch (std::exception& e) {
+ LOG("Unable to get url for title %s: ", cTitle.c_str());
+ LOG(e.what());
+ }
+
+ return JNI_FALSE;
+}
+
+JNIEXPORT jstring JNICALL Java_org_kiwix_kiwixlib_JNIKiwixReader_getTitle(
+ JNIEnv* env, jobject obj)
+{
+ jstring title;
+
+ try {
+ std::string cTitle = READER->getTitle();
+ title = c2jni(cTitle, env);
+ } catch (std::exception& e) {
+ LOG("Unable to get zim title");
+ LOG(e.what());
+ title = NULL;
+ }
+ return title;
+}
+
+JNIEXPORT jstring JNICALL
+Java_org_kiwix_kiwixlib_JNIKiwixReader_getDescription(JNIEnv* env, jobject obj)
+{
+ jstring description;
+
+ try {
+ std::string cDescription = READER->getDescription();
+ description = c2jni(cDescription, env);
+ } catch (std::exception& e) {
+ LOG("Unable to get zim description");
+ LOG(e.what());
+ description = NULL;
+ }
+ return description;
+}
+
+JNIEXPORT jint JNICALL
+Java_org_kiwix_kiwixlib_JNIKiwixReader_getArticleCount(JNIEnv* env, jobject obj)
+{
+ jint articleCount = 0;
+ try {
+ auto cArticleCount = READER->getArticleCount();
+ articleCount = c2jni(cArticleCount, env);
+ } catch (std::exception& e) {
+ LOG("Unable to get article count.");
+ LOG(e.what());
+ }
+ return articleCount;
+}
+
+JNIEXPORT jint JNICALL
+Java_org_kiwix_kiwixlib_JNIKiwixReader_getMediaCount(JNIEnv* env, jobject obj)
+{
+ jint mediaCount = 0;
+ try {
+ auto cMediaCount = READER->getMediaCount();
+ mediaCount = c2jni(cMediaCount, env);
+ } catch (std::exception& e) {
+ LOG("Unable to get media count.");
+ LOG(e.what());
+ }
+ return mediaCount;
+}
+
+
+JNIEXPORT jboolean JNICALL Java_org_kiwix_kiwixlib_JNIKiwixReader_getRandomPage(
+ JNIEnv* env, jobject obj, jobject urlObj)
+{
+ jboolean retVal = JNI_FALSE;
+ std::string cUrl;
+
+ try {
+ std::string cUrl = READER->getRandomPage().getPath();
+ setStringObjValue(cUrl, urlObj, env);
+ retVal = JNI_TRUE;
+ } catch (std::exception& e) {
+ LOG("Unable to get random page");
+ LOG(e.what());
+ }
+ return retVal;
+}
diff --git a/src/wrapper/java/kiwixsearcher.cpp b/src/wrapper/java/kiwixsearcher.cpp
new file mode 100644
index 0000000..de5f078
--- /dev/null
+++ b/src/wrapper/java/kiwixsearcher.cpp
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2013 Emmanuel Engelhart
+ * Copyright (C) 2017 Matthieu Gautier
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+
+#include
+#include "org_kiwix_kiwixlib_JNIKiwixSearcher.h"
+#include "org_kiwix_kiwixlib_JNIKiwixSearcher_Result.h"
+
+#include "reader.h"
+#include "searcher.h"
+#include "utils.h"
+
+#define SEARCHER (Handle::getHandle(env, obj))
+#define RESULT (Handle::getHandle(env, obj))
+
+
+JNIEXPORT void JNICALL
+Java_org_kiwix_kiwixlib_JNIKiwixSearcher_dispose(JNIEnv* env, jobject obj)
+{
+ Handle::dispose(env, obj);
+}
+
+/* Kiwix Reader JNI functions */
+JNIEXPORT jlong JNICALL
+Java_org_kiwix_kiwixlib_JNIKiwixSearcher_getNativeHandle(JNIEnv* env,
+ jobject obj)
+{
+ kiwix::Searcher* searcher = new kiwix::Searcher();
+ return reinterpret_cast(new Handle(searcher));
+}
+
+/* Kiwix library functions */
+JNIEXPORT void JNICALL Java_org_kiwix_kiwixlib_JNIKiwixSearcher_addReader(
+ JNIEnv* env, jobject obj, jobject reader)
+{
+ auto searcher = SEARCHER;
+
+ searcher->add_reader(*(Handle::getHandle(env, reader)));
+}
+
+JNIEXPORT void JNICALL Java_org_kiwix_kiwixlib_JNIKiwixSearcher_search(
+ JNIEnv* env, jobject obj, jstring query, jint count)
+{
+ std::string cquery = jni2c(query, env);
+ unsigned int ccount = jni2c(count, env);
+
+ SEARCHER->search(cquery, 0, ccount);
+}
+
+JNIEXPORT jobject JNICALL
+Java_org_kiwix_kiwixlib_JNIKiwixSearcher_getNextResult(JNIEnv* env,
+ jobject obj)
+{
+ jobject result = nullptr;
+
+ kiwix::Result* cresult = SEARCHER->getNextResult();
+ if (cresult != nullptr) {
+ jclass resultclass
+ = env->FindClass("org/kiwix/kiwixlib/JNIKiwixSearcher$Result");
+ jmethodID ctor = env->GetMethodID(
+ resultclass, "", "(Lorg/kiwix/kiwixlib/JNIKiwixSearcher;JLorg/kiwix/kiwixlib/JNIKiwixSearcher;)V");
+ result = env->NewObject(resultclass, ctor, obj, reinterpret_cast(new Handle(cresult)), obj);
+ }
+ return result;
+}
+
+JNIEXPORT void JNICALL Java_org_kiwix_kiwixlib_JNIKiwixSearcher_00024Result_dispose(
+ JNIEnv* env, jobject obj)
+{
+ Handle::dispose(env, obj);
+}
+
+JNIEXPORT jstring JNICALL
+Java_org_kiwix_kiwixlib_JNIKiwixSearcher_00024Result_getUrl(JNIEnv* env,
+ jobject obj)
+{
+ try {
+ return c2jni(RESULT->get_url(), env);
+ } catch (...) {
+ return nullptr;
+ }
+}
+
+JNIEXPORT jstring JNICALL
+Java_org_kiwix_kiwixlib_JNIKiwixSearcher_00024Result_getTitle(JNIEnv* env,
+ jobject obj)
+{
+ try {
+ return c2jni(RESULT->get_title(), env);
+ } catch (...) {
+ return nullptr;
+ }
+}
+
+JNIEXPORT jstring JNICALL
+Java_org_kiwix_kiwixlib_JNIKiwixSearcher_00024Result_getSnippet(JNIEnv* env,
+ jobject obj)
+{
+ return c2jni(RESULT->get_snippet(), env);
+}
+
+JNIEXPORT jstring JNICALL
+Java_org_kiwix_kiwixlib_JNIKiwixSearcher_00024Result_getContent(JNIEnv* env,
+ jobject obj)
+{
+ return c2jni(RESULT->get_content(), env);
+}
diff --git a/src/wrapper/java/kiwixserver.cpp b/src/wrapper/java/kiwixserver.cpp
new file mode 100644
index 0000000..7242c4c
--- /dev/null
+++ b/src/wrapper/java/kiwixserver.cpp
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2013 Emmanuel Engelhart
+ * Copyright (C) 2017 Matthieu Gautier
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+
+#include
+#include
+#include "org_kiwix_kiwixlib_JNIKiwixServer.h"
+
+#include "tools/base64.h"
+#include "server.h"
+#include "utils.h"
+
+/* Kiwix Reader JNI functions */
+JNIEXPORT jlong JNICALL Java_org_kiwix_kiwixlib_JNIKiwixServer_getNativeServer(
+ JNIEnv* env, jobject obj, jobject jLibrary)
+{
+ LOG("Attempting to create server");
+ Lock l;
+ try {
+ auto library = getPtr(env, jLibrary);
+ kiwix::Server* server = new kiwix::Server(library);
+ return reinterpret_cast(new Handle(server));
+ } catch (std::exception& e) {
+ LOG("Error creating the server");
+ LOG(e.what());
+ return 0;
+ }
+}
+
+JNIEXPORT void JNICALL
+Java_org_kiwix_kiwixlib_JNIKiwixServer_dispose(JNIEnv* env, jobject obj)
+{
+ Handle::dispose(env, obj);
+}
+
+#define SERVER (Handle::getHandle(env, obj))
+
+/* Kiwix library functions */
+JNIEXPORT void JNICALL
+Java_org_kiwix_kiwixlib_JNIKiwixServer_setRoot(JNIEnv* env, jobject obj, jstring jRoot)
+{
+ std::string root = jni2c(jRoot, env);
+ SERVER->setRoot(root);
+}
+
+JNIEXPORT void JNICALL
+Java_org_kiwix_kiwixlib_JNIKiwixServer_setAddress(JNIEnv* env, jobject obj, jstring jAddress)
+{
+ std::string address = jni2c(jAddress, env);
+ SERVER->setAddress(address);
+}
+
+JNIEXPORT void JNICALL
+Java_org_kiwix_kiwixlib_JNIKiwixServer_setPort(JNIEnv* env, jobject obj, int port)
+{
+ SERVER->setPort(port);
+}
+
+JNIEXPORT void JNICALL
+Java_org_kiwix_kiwixlib_JNIKiwixServer_setNbThreads(JNIEnv* env, jobject obj, int threads)
+{
+ SERVER->setNbThreads(threads);
+}
+
+JNIEXPORT void JNICALL
+Java_org_kiwix_kiwixlib_JNIKiwixServer_setTaskbar(JNIEnv* env, jobject obj, jboolean withTaskbar, jboolean withLibraryButton)
+{
+ SERVER->setTaskbar(withTaskbar, withLibraryButton);
+}
+
+JNIEXPORT jboolean JNICALL
+Java_org_kiwix_kiwixlib_JNIKiwixServer_start(JNIEnv* env, jobject obj)
+{
+ return SERVER->start();
+}
+
+JNIEXPORT void JNICALL
+Java_org_kiwix_kiwixlib_JNIKiwixServer_stop(JNIEnv* env, jobject obj)
+{
+ SERVER->stop();
+}
diff --git a/src/wrapper/java/library.cpp b/src/wrapper/java/library.cpp
new file mode 100644
index 0000000..f2a0846
--- /dev/null
+++ b/src/wrapper/java/library.cpp
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2019-2020 Matthieu Gautier
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+
+#include
+#include "org_kiwix_kiwixlib_Library.h"
+
+#include "library.h"
+#include "reader.h"
+#include "utils.h"
+
+/* Kiwix Reader JNI functions */
+JNIEXPORT void JNICALL
+Java_org_kiwix_kiwixlib_Library_allocate(
+ JNIEnv* env, jobject thisObj)
+{
+ allocate(env, thisObj);
+}
+
+JNIEXPORT void JNICALL
+Java_org_kiwix_kiwixlib_Library_dispose(JNIEnv* env, jobject thisObj)
+{
+ dispose(env, thisObj);
+}
+
+#define LIBRARY (getPtr(env, thisObj))
+
+/* Kiwix library functions */
+JNIEXPORT jboolean JNICALL
+Java_org_kiwix_kiwixlib_Library_addBook(
+ JNIEnv* env, jobject thisObj, jstring path)
+{
+ auto cPath = jni2c(path, env);
+
+ try {
+ kiwix::Reader reader(cPath);
+ kiwix::Book book;
+ book.update(reader);
+ return LIBRARY->addBook(book);
+ } catch (std::exception& e) {
+ LOG("Unable to add the book");
+ LOG(e.what()); }
+ return false;
+}
+
+METHOD(jobject, Library, getBookById, jstring id) {
+ auto cId = jni2c(id, env);
+ auto cBook = new kiwix::Book(LIBRARY->getBookById(cId));
+ jclass cls = env->FindClass("org/kiwix/kiwixlib/Book");
+ jmethodID constructorId = env->GetMethodID(cls, "", "()V");
+ jobject book = env->NewObject(cls, constructorId);
+ setPtr(env, book, cBook);
+ return book;
+}
+
+METHOD(jint, Library, getBookCount, jboolean localBooks, jboolean remoteBooks) {
+ return LIBRARY->getBookCount(localBooks, remoteBooks);
+}
+
+METHOD0(jobjectArray, Library, getBooksIds) {
+ return c2jni(LIBRARY->getBooksIds(), env);
+}
+
+METHOD(jobjectArray, Library, filter, jobject filterObj) {
+ auto filter = getPtr(env, filterObj);
+ return c2jni(LIBRARY->filter(*filter), env);
+}
+
+METHOD0(jobjectArray, Library, getBooksLanguages) {
+ return c2jni(LIBRARY->getBooksLanguages(), env);
+}
+
+METHOD0(jobjectArray, Library, getBooksCreators) {
+ return c2jni(LIBRARY->getBooksCreators(), env);
+}
+
+METHOD0(jobjectArray, Library, getBooksPublisher) {
+ return c2jni(LIBRARY->getBooksPublishers(), env);
+}
+
diff --git a/src/wrapper/java/manager.cpp b/src/wrapper/java/manager.cpp
new file mode 100644
index 0000000..b2e94d9
--- /dev/null
+++ b/src/wrapper/java/manager.cpp
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2020 Matthieu Gautier
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+
+#include
+#include
+#include "org_kiwix_kiwixlib_Manager.h"
+
+#include "manager.h"
+#include "utils.h"
+
+
+JNIEXPORT void JNICALL
+Java_org_kiwix_kiwixlib_Manager_allocate(
+ JNIEnv* env, jobject thisObj, jobject libraryObj)
+{
+ auto lib = getPtr(env, libraryObj);
+ allocate(env, thisObj, lib);
+}
+
+JNIEXPORT void JNICALL
+Java_org_kiwix_kiwixlib_Manager_dispose(JNIEnv* env, jobject thisObj)
+{
+ dispose(env, thisObj);
+}
+
+#define MANAGER (getPtr(env, thisObj))
+
+/* Kiwix manager functions */
+JNIEXPORT jboolean JNICALL
+Java_org_kiwix_kiwixlib_Manager_readFile(
+ JNIEnv* env, jobject thisObj, jstring path)
+{
+ auto cPath = jni2c(path, env);
+
+ try {
+ return MANAGER->readFile(cPath);
+ } catch (std::exception& e) {
+ LOG("Unable to get readFile");
+ LOG(e.what());
+ }
+ return false;
+}
+
+JNIEXPORT jboolean JNICALL
+Java_org_kiwix_kiwixlib_Manager_readXml(
+ JNIEnv* env, jobject thisObj, jstring content, jstring libraryPath)
+{
+ auto cContent = jni2c(content, env);
+ auto cPath = jni2c(libraryPath, env);
+
+ try {
+ return MANAGER->readXml(cContent, false, cPath);
+ } catch (std::exception& e) {
+ LOG("Unable to get ZIM id");
+ LOG(e.what());
+ }
+
+ return false;
+}
+
+JNIEXPORT jboolean JNICALL
+Java_org_kiwix_kiwixlib_Manager_readOpds(
+ JNIEnv* env, jobject thisObj, jstring content, jstring urlHost)
+{
+ auto cContent = jni2c(content, env);
+ auto cUrl = jni2c(urlHost, env);
+
+ try {
+ return MANAGER->readOpds(cContent, cUrl);
+ } catch (std::exception& e) {
+ LOG("Unable to get ZIM id");
+ LOG(e.what());
+ }
+
+ return false;
+}
+
+JNIEXPORT jboolean JNICALL
+Java_org_kiwix_kiwixlib_Manager_readBookmarkFile(
+ JNIEnv* env, jobject thisObj, jstring path)
+{
+ auto cPath = jni2c(path, env);
+
+ try {
+ return MANAGER->readBookmarkFile(cPath);
+ } catch (std::exception& e) {
+ LOG("Unable to get ZIM id");
+ LOG(e.what());
+ }
+
+ return false;
+}
+
+JNIEXPORT jstring JNICALL
+Java_org_kiwix_kiwixlib_Manager_addBookFromPath(
+ JNIEnv* env, jobject thisObj,
+ jstring pathToOpen, jstring pathToSave, jstring url, jboolean checkMetaData)
+{
+ auto cPathToOpen = jni2c(pathToOpen, env);
+ auto cPathToSave = jni2c(pathToSave, env);
+ auto cUrl = jni2c(url, env);
+ jstring id = NULL;
+
+ try {
+ auto cId = MANAGER->addBookFromPathAndGetId(cPathToOpen, cPathToSave, cUrl, checkMetaData);
+ if ( !cId.empty() ) {
+ id = c2jni(cId, env);
+ }
+ } catch (std::exception& e) {
+ LOG("Unable to get ZIM file size");
+ LOG(e.what());
+ }
+
+ return id;
+}
diff --git a/src/wrapper/java/meson.build b/src/wrapper/java/meson.build
new file mode 100644
index 0000000..0341730
--- /dev/null
+++ b/src/wrapper/java/meson.build
@@ -0,0 +1,55 @@
+
+java_sources = files([
+ 'org/kiwix/kiwixlib/JNIICU.java',
+ 'org/kiwix/kiwixlib/Book.java',
+ 'org/kiwix/kiwixlib/JNIKiwixReader.java',
+ 'org/kiwix/kiwixlib/Library.java',
+ 'org/kiwix/kiwixlib/Manager.java',
+ 'org/kiwix/kiwixlib/Filter.java',
+ 'org/kiwix/kiwixlib/JNIKiwixSearcher.java',
+ 'org/kiwix/kiwixlib/JNIKiwixServer.java',
+ 'org/kiwix/kiwixlib/JNIKiwixInt.java',
+ 'org/kiwix/kiwixlib/JNIKiwixString.java',
+ 'org/kiwix/kiwixlib/JNIKiwixBool.java',
+ 'org/kiwix/kiwixlib/JNIKiwixException.java',
+ 'org/kiwix/kiwixlib/Pair.java'
+])
+
+kiwix_jni = custom_target('jni',
+ input: java_sources,
+ output: ['org_kiwix_kiwixlib_JNIKiwix.h',
+ 'org_kiwix_kiwixlib_Book.h',
+ 'org_kiwix_kiwixlib_JNIKiwixReader.h',
+ 'org_kiwix_kiwixlib_Library.h',
+ 'org_kiwix_kiwixlib_Manager.h',
+ 'org_kiwix_kiwixlib_Filter.h',
+ 'org_kiwix_kiwixlib_JNIKiwixServer.h',
+ 'org_kiwix_kiwixlib_JNIKiwixSearcher.h',
+ 'org_kiwix_kiwixlib_JNIKiwixSearcher_Result.h'],
+ command:['javac', '-d', '@OUTDIR@', '-h', '@OUTDIR@', '@INPUT@']
+)
+
+jni_sources = files([
+ 'kiwixicu.cpp',
+ 'book.cpp',
+ 'kiwixreader.cpp',
+ 'library.cpp',
+ 'manager.cpp',
+ 'filter.cpp',
+ 'kiwixsearcher.cpp',
+ 'kiwixserver.cpp',
+])
+
+kiwix_sources += jni_sources + [kiwix_jni]
+
+if 'java' in wrapper
+ kiwix_jar = jar('kiwixlib', java_sources)
+ #junit_jar = files('org/kiwix/testing/junit-4.13.jar')
+ #test_jar = jar('testing', 'org/kiwix/testing/test.java',
+ # link_with: [kiwix_jar, junit_jar])
+ #test('javatest', test_jar)
+endif
+
+install_subdir('org', install_dir: 'kiwix-lib/java', exclude_directories: ['kiwix/testing'])
+install_subdir('res', install_dir: 'kiwix-lib')
+install_data('AndroidManifest.xml', install_dir: 'kiwix-lib')
diff --git a/src/wrapper/java/org/kiwix/kiwixlib/Book.java b/src/wrapper/java/org/kiwix/kiwixlib/Book.java
new file mode 100644
index 0000000..06b72e1
--- /dev/null
+++ b/src/wrapper/java/org/kiwix/kiwixlib/Book.java
@@ -0,0 +1,35 @@
+
+package org.kiwix.kiwixlib;
+
+public class Book
+{
+ public Book() { allocate(); }
+
+ @Override
+ protected void finalize() { dispose(); }
+
+ public native String getId();
+ public native String getPath();
+ public native boolean isPathValid();
+ public native String getTitle();
+ public native String getDescription();
+ public native String getLanguage();
+ public native String getCreator();
+ public native String getPublisher();
+ public native String getDate();
+ public native String getUrl();
+ public native String getName();
+ public native String getTags();
+
+ public native long getArticleCount();
+ public native long getMediaCount();
+ public native long getSize();
+
+ public native String getFavicon();
+ public native String getFaviconUrl();
+ public native String getFaviconMimeType();
+
+ private native void allocate();
+ private native void dispose();
+ private long nativeHandle;
+}
diff --git a/src/wrapper/java/org/kiwix/kiwixlib/Filter.java b/src/wrapper/java/org/kiwix/kiwixlib/Filter.java
new file mode 100644
index 0000000..bf9e719
--- /dev/null
+++ b/src/wrapper/java/org/kiwix/kiwixlib/Filter.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2019-2020 Matthieu Gautier
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+package org.kiwix.kiwixlib;
+
+public class Filter
+{
+
+ public native Filter local(boolean accept);
+ public native Filter remote(boolean accept);
+ public native Filter valid(boolean accept);
+ public native Filter acceptTags(String[] tags);
+ public native Filter rejectTags(String[] tags);
+ public native Filter lang(String lang);
+ public native Filter publisher(String publisher);
+ public native Filter creator(String creator);
+ public native Filter maxSize(long size);
+ public native Filter query(String query);
+
+
+ public Filter() { allocate(); }
+
+ @Override
+ protected void finalize() { dispose(); }
+ private native void allocate();
+ private native void dispose();
+ private long nativeHandle;
+}
diff --git a/src/wrapper/java/org/kiwix/kiwixlib/JNIICU.java b/src/wrapper/java/org/kiwix/kiwixlib/JNIICU.java
new file mode 100644
index 0000000..db8ba6e
--- /dev/null
+++ b/src/wrapper/java/org/kiwix/kiwixlib/JNIICU.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2013 Emmanuel Engelhart
+ * Copyright (C) 2017 Matthieu Gautier
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+package org.kiwix.kiwixlib;
+
+public class JNIICU
+{
+ static public native void setDataDirectory(String icuDataDir);
+}
diff --git a/src/wrapper/java/org/kiwix/kiwixlib/JNIKiwix.java b/src/wrapper/java/org/kiwix/kiwixlib/JNIKiwix.java
new file mode 100644
index 0000000..57e148b
--- /dev/null
+++ b/src/wrapper/java/org/kiwix/kiwixlib/JNIKiwix.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2013 Emmanuel Engelhart
+ * Copyright (C) 2017 Matthieu Gautier
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+package org.kiwix.kiwixlib;
+
+import android.content.Context;
+import com.getkeepsafe.relinker.ReLinker;
+import org.kiwix.kiwixlib.JNIICU;
+
+public class JNIKiwix
+{
+ public JNIKiwix(final Context context){
+ ReLinker.loadLibrary(context, "kiwix");
+ }
+
+ public void setDataDirectory(String icuDataDir) {
+ JNIICU.setDataDirectory(icuDataDir);
+ }
+}
diff --git a/src/wrapper/java/org/kiwix/kiwixlib/JNIKiwixBool.java b/src/wrapper/java/org/kiwix/kiwixlib/JNIKiwixBool.java
new file mode 100644
index 0000000..74563d3
--- /dev/null
+++ b/src/wrapper/java/org/kiwix/kiwixlib/JNIKiwixBool.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2013 Emmanuel Engelhart
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+package org.kiwix.kiwixlib;
+
+public class JNIKiwixBool
+{
+ public boolean value;
+}
diff --git a/src/wrapper/java/org/kiwix/kiwixlib/JNIKiwixException.java b/src/wrapper/java/org/kiwix/kiwixlib/JNIKiwixException.java
new file mode 100644
index 0000000..dd0e214
--- /dev/null
+++ b/src/wrapper/java/org/kiwix/kiwixlib/JNIKiwixException.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2017 Matthieu Gautier
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+package org.kiwix.kiwixlib;
+
+public class JNIKiwixException extends Exception
+{
+ public JNIKiwixException(String message) {
+ super(message);
+ }
+}
diff --git a/src/wrapper/java/org/kiwix/kiwixlib/JNIKiwixInt.java b/src/wrapper/java/org/kiwix/kiwixlib/JNIKiwixInt.java
new file mode 100644
index 0000000..a66c937
--- /dev/null
+++ b/src/wrapper/java/org/kiwix/kiwixlib/JNIKiwixInt.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2013 Emmanuel Engelhart
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+package org.kiwix.kiwixlib;
+
+public class JNIKiwixInt
+{
+ public int value;
+}
diff --git a/src/wrapper/java/org/kiwix/kiwixlib/JNIKiwixReader.java b/src/wrapper/java/org/kiwix/kiwixlib/JNIKiwixReader.java
new file mode 100644
index 0000000..0da29ed
--- /dev/null
+++ b/src/wrapper/java/org/kiwix/kiwixlib/JNIKiwixReader.java
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2013 Emmanuel Engelhart
+ * Copyright (C) 2017 Matthieu Gautier
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+package org.kiwix.kiwixlib;
+
+import org.kiwix.kiwixlib.JNIKiwixException;
+import org.kiwix.kiwixlib.JNIKiwixString;
+import org.kiwix.kiwixlib.JNIKiwixInt;
+import org.kiwix.kiwixlib.JNIKiwixSearcher;
+import org.kiwix.kiwixlib.Pair;
+
+public class JNIKiwixReader
+{
+ public native String getMainPage();
+
+ public native String getTitle();
+
+ public native String getId();
+
+ public native String getLanguage();
+
+ public native String getMimeType(String url);
+
+ /**
+ * Check if a url exists and is a redirect or not.
+ *
+ * Return an empty string if the url doesn't exist in the reader.
+ * Return the url of the "final" entry.
+ * - equal to the input url if the entry is not a redirection.
+ * - different if the url is a redirection (and the webview should redirect to it).
+ */
+ public native String checkUrl(String url);
+
+ /**
+ * Get the content of a article.
+ *
+ * Return a byte array of the content of the article.
+ * Set the title, mimeType to the title and mimeType of the article.
+ * Set the size to the size of the returned array.
+ *
+ * If the entry doesn't exist :
+ * - return a empty byte array
+ * - set all arguments (except url) to empty/0.
+ * If the entry exist but is a redirection :
+ * - return an empty byte array
+ * - set all arguments (including url) to information of the targeted article.
+ */
+ public native byte[] getContent(JNIKiwixString url,
+ JNIKiwixString title,
+ JNIKiwixString mimeType,
+ JNIKiwixInt size);
+
+ /**
+ * getContentPart.
+ *
+ * Get only a part of the content of the article.
+ * Return a byte array of `len` size starting from offset `offset`.
+ * Set `size` to the number of bytes read
+ * (`len` if everything is ok, 0 in case of error).
+ * If `len` == 0, no bytes are read but `size` is set to the total size of the
+ * article.
+ */
+ public native byte[] getContentPart(String url,
+ int offest,
+ int len,
+ JNIKiwixInt size);
+
+ /**
+ * getDirectAccessInformation.
+ *
+ * Return information giving where the content is located in the zim file.
+ *
+ * Some contents (binary content) are stored uncompressed in the zim file.
+ * Knowing this information, it could be interesting to directly open
+ * the zim file (or zim part) and directly read the content from it (and so
+ * bypassing the libzim).
+ *
+ * Return a `Pair` (filename, offset) where the content is located.
+ *
+ * If the content cannot be directly accessed (content is compressed or zim
+ * file is cut in the middle of the content), the filename is an empty string
+ * and offset is zero.
+ */
+ public native Pair getDirectAccessInformation(String url);
+
+ public native boolean searchSuggestions(String prefix, int count);
+
+ public native boolean getNextSuggestion(JNIKiwixString title, JNIKiwixString url);
+
+ public native boolean getPageUrlFromTitle(String title, JNIKiwixString url);
+
+ public native String getDescription();
+
+ public native String getDate();
+
+ public native String getFavicon();
+
+ public native String getCreator();
+
+ public native String getPublisher();
+
+ public native String getName();
+
+ public native int getFileSize();
+
+ public native int getArticleCount();
+
+ public native int getMediaCount();
+
+ public native boolean getRandomPage(JNIKiwixString url);
+
+ public JNIKiwixSearcher search(String query, int count)
+ {
+ JNIKiwixSearcher searcher = new JNIKiwixSearcher();
+ searcher.addKiwixReader(this);
+ searcher.search(query, count);
+ return searcher;
+ }
+
+ public JNIKiwixReader(String filename) throws JNIKiwixException
+ {
+ nativeHandle = getNativeReader(filename);
+ if (nativeHandle == 0) {
+ throw new JNIKiwixException("Cannot open zimfile "+filename);
+ }
+ }
+ public JNIKiwixReader() {
+
+ }
+ public native void dispose();
+
+ private native long getNativeReader(String filename);
+ private long nativeHandle;
+}
diff --git a/src/wrapper/java/org/kiwix/kiwixlib/JNIKiwixSearcher.java b/src/wrapper/java/org/kiwix/kiwixlib/JNIKiwixSearcher.java
new file mode 100644
index 0000000..30d7afb
--- /dev/null
+++ b/src/wrapper/java/org/kiwix/kiwixlib/JNIKiwixSearcher.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2013 Emmanuel Engelhart
+ * Copyright (C) 2017 Matthieu Gautier
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+
+package org.kiwix.kiwixlib;
+
+import org.kiwix.kiwixlib.JNIKiwixReader;
+import java.util.Vector;
+
+public class JNIKiwixSearcher
+{
+ public class Result
+ {
+ private long nativeHandle;
+ private JNIKiwixSearcher searcher;
+ public Result(long handle, JNIKiwixSearcher _searcher)
+ {
+ nativeHandle = handle;
+ searcher = _searcher;
+ }
+ public native String getUrl();
+ public native String getTitle();
+ public native String getContent();
+ public native String getSnippet();
+ public native void dispose();
+ }
+
+ public JNIKiwixSearcher()
+ {
+ nativeHandle = getNativeHandle();
+ usedReaders = new Vector();
+ }
+ public native void dispose();
+
+ private native long getNativeHandle();
+ private long nativeHandle;
+ private Vector usedReaders;
+
+ public native void addReader(JNIKiwixReader reader);
+ public void addKiwixReader(JNIKiwixReader reader)
+ {
+ addReader(reader);
+ usedReaders.addElement(reader);
+ };
+
+ public native void search(String query, int count);
+
+ public native Result getNextResult();
+ public native boolean hasMoreResult();
+}
diff --git a/src/wrapper/java/org/kiwix/kiwixlib/JNIKiwixServer.java b/src/wrapper/java/org/kiwix/kiwixlib/JNIKiwixServer.java
new file mode 100644
index 0000000..578e2f4
--- /dev/null
+++ b/src/wrapper/java/org/kiwix/kiwixlib/JNIKiwixServer.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2019 Matthieu Gautier
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+package org.kiwix.kiwixlib;
+
+import org.kiwix.kiwixlib.JNIKiwixException;
+import org.kiwix.kiwixlib.Library;
+
+public class JNIKiwixServer
+{
+ public native void setRoot(String root);
+
+ public native void setAddress(String address);
+
+ public native void setPort(int port);
+
+ public native void setNbThreads(int nbTreads);
+
+ public native void setTaskbar(boolean withTaskBar, boolean witLibraryButton);
+
+ public native boolean start();
+
+ public native void stop();
+
+ public JNIKiwixServer(Library library)
+ {
+ nativeHandle = getNativeServer(library);
+ }
+
+ private native long getNativeServer(Library library);
+ private long nativeHandle;
+}
diff --git a/src/wrapper/java/org/kiwix/kiwixlib/JNIKiwixString.java b/src/wrapper/java/org/kiwix/kiwixlib/JNIKiwixString.java
new file mode 100644
index 0000000..601fb9d
--- /dev/null
+++ b/src/wrapper/java/org/kiwix/kiwixlib/JNIKiwixString.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2013 Emmanuel Engelhart
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+package org.kiwix.kiwixlib;
+
+public class JNIKiwixString
+{
+ public String value;
+
+ public JNIKiwixString(String value) {
+ this.value = value;
+ }
+
+ public JNIKiwixString() {
+ this("");
+ }
+
+ public String getValue() {
+ return value;
+ }
+}
diff --git a/src/wrapper/java/org/kiwix/kiwixlib/Library.java b/src/wrapper/java/org/kiwix/kiwixlib/Library.java
new file mode 100644
index 0000000..68aa7d2
--- /dev/null
+++ b/src/wrapper/java/org/kiwix/kiwixlib/Library.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2019-2020 Matthieu Gautier
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+package org.kiwix.kiwixlib;
+
+import org.kiwix.kiwixlib.Book;
+import org.kiwix.kiwixlib.JNIKiwixException;
+
+public class Library
+{
+ public native boolean addBook(String path) throws JNIKiwixException;
+
+ public native Book getBookById(String id);
+ public native int getBookCount(boolean localBooks, boolean remoteBooks);
+
+ public native String[] getBooksIds();
+ public native String[] filter(Filter filter);
+
+ public native String[] getBooksLanguages();
+ public native String[] getBooksCreators();
+ public native String[] getBooksPublishers();
+
+ public Library()
+ {
+ allocate();
+ }
+
+ @Override
+ protected void finalize() { dispose(); }
+ private native void allocate();
+ private native void dispose();
+ private long nativeHandle;
+}
diff --git a/src/wrapper/java/org/kiwix/kiwixlib/Manager.java b/src/wrapper/java/org/kiwix/kiwixlib/Manager.java
new file mode 100644
index 0000000..2772ca9
--- /dev/null
+++ b/src/wrapper/java/org/kiwix/kiwixlib/Manager.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2020 Matthieu Gautier
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+package org.kiwix.kiwixlib;
+
+import org.kiwix.kiwixlib.Library;
+
+public class Manager
+{
+ /**
+ * Read a `library.xml` file and add books in the library.
+ *
+ * @param path The (utf8) path to the `library.xml` file.
+ * @return True if the file has been properly parsed.
+ */
+ public native boolean readFile(String path);
+
+ /**
+ * Load a library content stored in a string (at `library.xml` format).
+ *
+ * @param content The content corresponding of the library xml.
+ * @param libraryPath The library path (used to resolve relative paths)
+ * @return True if the content has been properly parsed.
+ */
+ public native boolean readXml(String content, String libraryPath);
+
+ /**
+ * Load a library content stored in a string (at OPDS stream format)
+ *
+ * @param content the content of the OPDS stream.
+ * @param urlHost the url of the stream (used to resolve relative url)
+ * @return True if the content has been properly parsed.
+ */
+ public native boolean readOpds(String content, String urlHost);
+
+ /**
+ * Load a bookmark file
+ *
+ * @param path The path of the file to read.
+ * @return True if the content has been properly parsed
+ */
+ public native boolean readBookmarkFile(String path);
+
+ /**
+ * Add a book to the library.
+ *
+ * @param pathToOpen The path of the zim file to add.
+ * @param pathToSave The path to store in the library in place of
+ * pathToOpen.
+ * @param url The url of the book to store in the library
+ * (useful for kiiwix-serve catalog)
+ * @param checkMetaData Tell if we check metadata before adding a book to the
+ * library.
+ * @return The id of te book if the book has been added to the library.
+ * Empty string if not.
+ */
+ public native String addBookFromPath(String pathToOpen,
+ String pathToSave,
+ String url,
+ boolean checkMetaData);
+
+ public Manager(Library library) {
+ allocate(library);
+ _library = library;
+ }
+
+ private Library _library;
+
+ @Override
+ protected void finalize() { dispose(); }
+ private native void allocate(Library library);
+ private native void dispose();
+ private long nativeHandle;
+}
diff --git a/src/wrapper/java/org/kiwix/kiwixlib/Pair.java b/src/wrapper/java/org/kiwix/kiwixlib/Pair.java
new file mode 100644
index 0000000..ef49e1b
--- /dev/null
+++ b/src/wrapper/java/org/kiwix/kiwixlib/Pair.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2017 Matthieu Gautier
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+package org.kiwix.kiwixlib;
+
+public class Pair
+{
+ public String filename;
+ public int offset;
+}
diff --git a/src/wrapper/java/org/kiwix/testing/compile_test.sh b/src/wrapper/java/org/kiwix/testing/compile_test.sh
new file mode 100755
index 0000000..a985699
--- /dev/null
+++ b/src/wrapper/java/org/kiwix/testing/compile_test.sh
@@ -0,0 +1,26 @@
+#!/usr/bin/bash
+
+# This script compile the unit test to test the java wrapper.
+# This is not integrated in meson because ... this is not so easy.
+
+
+KIWIX_LIB_JAR=$1
+if [ -z $KIWIX_LIB_JAR ]
+then
+ echo "You must give the path to the kiwixlib.jar as first argument"
+ exit 1
+fi
+
+KIWIX_LIB_DIR=$2
+if [ -z $KIWIX_LIB_DIR ]
+then
+ echo "You must give the path to directory containing libkiwix.so as second argument"
+ exit 1
+fi
+TEST_SOURCE_DIR=$(dirname $(readlink -f $0))
+
+
+javac -g -d . -s . -cp $TEST_SOURCE_DIR/junit-4.13.jar:$KIWIX_LIB_JAR $TEST_SOURCE_DIR/test.java
+
+java -Djava.library.path=$KIWIX_LIB_DIR -cp $TEST_SOURCE_DIR/junit-4.13.jar:$TEST_SOURCE_DIR/hamcrest-core-1.3.jar:$KIWIX_LIB_JAR:. org.junit.runner.JUnitCore test
+
diff --git a/src/wrapper/java/org/kiwix/testing/hamcrest-core-1.3.jar b/src/wrapper/java/org/kiwix/testing/hamcrest-core-1.3.jar
new file mode 100644
index 0000000..9d5fe16
Binary files /dev/null and b/src/wrapper/java/org/kiwix/testing/hamcrest-core-1.3.jar differ
diff --git a/src/wrapper/java/org/kiwix/testing/junit-4.13.jar b/src/wrapper/java/org/kiwix/testing/junit-4.13.jar
new file mode 100644
index 0000000..acc3c43
Binary files /dev/null and b/src/wrapper/java/org/kiwix/testing/junit-4.13.jar differ
diff --git a/src/wrapper/java/org/kiwix/testing/test.java b/src/wrapper/java/org/kiwix/testing/test.java
new file mode 100644
index 0000000..671b0b4
--- /dev/null
+++ b/src/wrapper/java/org/kiwix/testing/test.java
@@ -0,0 +1,53 @@
+
+import java.io.*;
+import java.util.*;
+import org.junit.Test;
+import static org.junit.Assert.*;
+import org.kiwix.kiwixlib.*;
+
+public class test {
+static {
+ System.loadLibrary("kiwix");
+}
+
+private static String getCatalogContent()
+throws IOException
+{
+ BufferedReader reader = new BufferedReader(new FileReader("catalog.xml"));
+ String line;
+ StringBuilder sb = new StringBuilder();
+ while ((line = reader.readLine()) != null)
+ {
+ sb.append(line + "\n");
+ }
+ reader.close();
+ return sb.toString();
+}
+
+@Test
+public void testSome()
+throws IOException
+{
+ Library lib = new Library();
+ Manager manager = new Manager(lib);
+ String content = getCatalogContent();
+ manager.readOpds(content, "https://library.kiwix.org");
+ assertEquals(lib.getBookCount(true, true), 10);
+ String[] bookIds = lib.getBooksIds();
+ assertEquals(bookIds.length, 10);
+ Book book = lib.getBookById(bookIds[0]);
+ assertEquals(book.getTitle(), "Wikisource");
+ assertEquals(book.getTags(), "wikisource;_category:wikisource;_pictures:no;_videos:no;_details:yes;_ftindex:yes");
+ assertEquals(book.getFaviconUrl(), "https://library.kiwix.org/meta?name=favicon&content=wikisource_fr_all_nopic_2020-01");
+ assertEquals(book.getUrl(), "http://download.kiwix.org/zim/wikisource/wikisource_fr_all_nopic_2020-01.zim.meta4");
+}
+
+static
+public void main(String[] args) {
+ Library lib = new Library();
+ lib.getBookCount(true, true);
+}
+
+
+
+}
diff --git a/src/wrapper/java/res/values/strings.xml b/src/wrapper/java/res/values/strings.xml
new file mode 100644
index 0000000..8386572
--- /dev/null
+++ b/src/wrapper/java/res/values/strings.xml
@@ -0,0 +1,3 @@
+
+ Kiwix Lib
+
diff --git a/src/wrapper/java/utils.h b/src/wrapper/java/utils.h
new file mode 100644
index 0000000..7fa32a1
--- /dev/null
+++ b/src/wrapper/java/utils.h
@@ -0,0 +1,271 @@
+/*
+ * Copyright (C) 2013 Emmanuel Engelhart
+ * Copyright (C) 2017 Matthieu Gautier
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+
+#ifndef _ANDROID_JNI_UTILS_H
+#define _ANDROID_JNI_UTILS_H
+
+#include
+
+#include
+#include
+#include
+#include
+
+#if __ANDROID__
+ #include
+ #define LOG(...) __android_log_print(ANDROID_LOG_ERROR, "kiwix", __VA_ARGS__)
+#else
+ #define LOG(...)
+#endif
+
+extern pthread_mutex_t globalLock;
+
+template
+void setPtr(JNIEnv* env, jobject thisObj, T* ptr)
+{
+ jclass thisClass = env->GetObjectClass(thisObj);
+ jfieldID fieldId = env->GetFieldID(thisClass, "nativeHandle", "J");
+ env->SetLongField(thisObj, fieldId, reinterpret_cast(ptr));
+}
+
+template
+void allocate(JNIEnv* env, jobject thisObj, Args && ...args)
+{
+ T* ptr = new T(std::forward(args)...);
+ setPtr(env, thisObj, ptr);
+}
+
+template
+T* getPtr(JNIEnv* env, jobject thisObj)
+{
+ jclass thisClass = env->GetObjectClass(thisObj);
+ jfieldID fidNumber = env->GetFieldID(thisClass, "nativeHandle", "J");
+ return reinterpret_cast(env->GetLongField(thisObj, fidNumber));
+}
+
+template
+void dispose(JNIEnv* env, jobject thisObj)
+{
+ delete getPtr(env, thisObj);
+}
+
+#define METHOD0(retType, class, name) \
+JNIEXPORT retType JNICALL Java_org_kiwix_kiwixlib_##class##_##name( \
+ JNIEnv* env, jobject thisObj)
+
+#define METHOD(retType, class, name, ...) \
+JNIEXPORT retType JNICALL Java_org_kiwix_kiwixlib_##class##_##name( \
+ JNIEnv* env, jobject thisObj, __VA_ARGS__)
+
+inline jfieldID getHandleField(JNIEnv* env, jobject obj)
+{
+ jclass c = env->GetObjectClass(obj);
+ // J is the type signature for long:
+ return env->GetFieldID(c, "nativeHandle", "J");
+}
+
+inline jobjectArray createArray(JNIEnv* env, size_t length, const std::string& type_sig)
+{
+ jclass c = env->FindClass(type_sig.c_str());
+ return env->NewObjectArray(length, c, NULL);
+}
+
+class Lock
+{
+ protected:
+ pthread_mutex_t* lock;
+
+ public:
+ Lock() : lock(&globalLock) { pthread_mutex_lock(lock); }
+ Lock(const Lock&) = delete;
+ Lock& operator=(const Lock&) = delete;
+ Lock(Lock&& other) : lock(&globalLock) { other.lock = nullptr; }
+ virtual ~Lock()
+ {
+ if (lock) {
+ pthread_mutex_unlock(lock);
+ }
+ }
+};
+
+template
+class LockedHandle;
+
+template
+class Handle
+{
+ protected:
+ T* h;
+
+ public:
+ Handle(T* h) : h(h){};
+
+ // No destructor. This must and will be handled by dispose method.
+
+ static LockedHandle getHandle(JNIEnv* env, jobject obj)
+ {
+ jlong handle = env->GetLongField(obj, getHandleField(env, obj));
+ return LockedHandle(reinterpret_cast*>(handle));
+ }
+
+ static void dispose(JNIEnv* env, jobject obj)
+ {
+ auto lHandle = getHandle(env, obj);
+ auto handle = lHandle.h;
+ delete handle->h;
+ delete handle;
+ }
+ friend class LockedHandle;
+};
+
+template
+struct LockedHandle : public Lock {
+ Handle* h;
+ LockedHandle(Handle* h) : h(h) {}
+ T* operator->() { return h->h; }
+ T* operator*() { return h->h; }
+ operator bool() const { return (h->h != nullptr); }
+ operator T*() const { return h->h; }
+};
+
+template
+struct JType { };
+
+template<> struct JType{ typedef jboolean type_t; };
+template<> struct JType{ typedef jint type_t; };
+template<> struct JType{ typedef jlong type_t; };
+template<> struct JType { typedef jlong type_t; };
+template<> struct JType { typedef jlong type_t; };
+template<> struct JType{ typedef jstring type_t; };
+template<> struct JType>{ typedef jobjectArray type_t; };
+
+template
+inline typename JType::type_t c2jni(const T& val, JNIEnv* env) {
+ return static_cast::type_t>(val);
+}
+
+template<>
+inline jboolean c2jni(const bool& val, JNIEnv* env) { return val ? JNI_TRUE : JNI_FALSE; }
+
+template<>
+inline jstring c2jni(const std::string& val, JNIEnv* env)
+{
+ return env->NewStringUTF(val.c_str());
+}
+
+template<>
+inline jobjectArray c2jni(const std::vector& val, JNIEnv* env)
+{
+ auto array = createArray(env, val.size(), "java/lang/String");
+ size_t index = 0;
+ for (auto& elem: val) {
+ auto jElem = c2jni(elem, env);
+ env->SetObjectArrayElement(array, index++, jElem);
+ }
+ return array;
+}
+
+template
+struct CType { };
+
+template<> struct CType{ typedef bool type_t; };
+template<> struct CType{ typedef int type_t; };
+template<> struct CType{ typedef long type_t; };
+template<> struct CType{ typedef std::string type_t; };
+
+template
+struct CType{ typedef std::vector::type_t> type_t; };
+
+/* jni2c type conversion functions */
+template
+inline typename CType::type_t jni2c(const T& val, JNIEnv* env) {
+ return static_cast::type_t>(val);
+}
+
+template<>
+inline bool jni2c(const jboolean& val, JNIEnv* env) { return val == JNI_TRUE; }
+
+template<>
+inline std::string jni2c(const jstring& val, JNIEnv* env)
+{
+ const char* chars = env->GetStringUTFChars(val, 0);
+ std::string ret(chars);
+ env->ReleaseStringUTFChars(val, chars);
+ return ret;
+}
+
+template
+inline typename CType::type_t jni2c(const jobjectArray& val, JNIEnv* env)
+{
+ jsize length = env->GetArrayLength(val);
+ typename CType::type_t v(length);
+
+ int i;
+ for (i = 0; i < length; i++) {
+ U obj = (U) env->GetObjectArrayElement(val, i);
+ auto cobj = jni2c(obj, env);
+ v.push_back(cobj);
+ }
+ return v;
+}
+
+/* Method to deal with variable passed by reference */
+inline std::string getStringObjValue(const jobject obj, JNIEnv* env)
+{
+ jclass objClass = env->GetObjectClass(obj);
+ jfieldID objFid = env->GetFieldID(objClass, "value", "Ljava/lang/String;");
+ jstring jstr = (jstring)env->GetObjectField(obj, objFid);
+ return jni2c(jstr, env);
+}
+inline void setStringObjValue(const std::string& value,
+ const jobject obj,
+ JNIEnv* env)
+{
+ jclass objClass = env->GetObjectClass(obj);
+ jfieldID objFid = env->GetFieldID(objClass, "value", "Ljava/lang/String;");
+ env->SetObjectField(obj, objFid, c2jni(value, env));
+}
+
+inline void setIntObjValue(const int value, const jobject obj, JNIEnv* env)
+{
+ jclass objClass = env->GetObjectClass(obj);
+ jfieldID objFid = env->GetFieldID(objClass, "value", "I");
+ env->SetIntField(obj, objFid, value);
+}
+
+inline void setBoolObjValue(const bool value, const jobject obj, JNIEnv* env)
+{
+ jclass objClass = env->GetObjectClass(obj);
+ jfieldID objFid = env->GetFieldID(objClass, "value", "Z");
+ env->SetIntField(obj, objFid, c2jni(value, env));
+}
+
+inline void setPairObjValue(const std::string& filename, const int offset,
+ const jobject obj, JNIEnv* env)
+{
+ jclass objClass = env->GetObjectClass(obj);
+ jfieldID filenameFid = env->GetFieldID(objClass, "filename", "Ljava/lang/String;");
+ env->SetObjectField(obj, filenameFid, c2jni(filename, env));
+ jfieldID offsetFid = env->GetFieldID(objClass, "offset", "I");
+ env->SetIntField(obj, offsetFid, offset);
+}
+
+#endif // _ANDROID_JNI_UTILS_H