[sword-svn] r3575 - in trunk/bindings: cordova/org.crosswire.sword.cordova.SWORD/src/android cordova/org.crosswire.sword.cordova.SWORD/www java-jni/jni java-jni/src/org/crosswire/android/sword

scribe at crosswire.org scribe at crosswire.org
Sun Mar 25 06:17:56 MST 2018


Author: scribe
Date: 2018-03-25 06:17:56 -0700 (Sun, 25 Mar 2018)
New Revision: 3575

Modified:
   trunk/bindings/cordova/org.crosswire.sword.cordova.SWORD/src/android/SWORD.java
   trunk/bindings/cordova/org.crosswire.sword.cordova.SWORD/www/SWORD.js
   trunk/bindings/java-jni/jni/swordstub.cpp
   trunk/bindings/java-jni/src/org/crosswire/android/sword/SWMgr.java
Log:
Added support for ModInfo.features array.  Reworked BibleSync interface

Modified: trunk/bindings/cordova/org.crosswire.sword.cordova.SWORD/src/android/SWORD.java
===================================================================
--- trunk/bindings/cordova/org.crosswire.sword.cordova.SWORD/src/android/SWORD.java	2018-03-11 21:59:28 UTC (rev 3574)
+++ trunk/bindings/cordova/org.crosswire.sword.cordova.SWORD/src/android/SWORD.java	2018-03-25 13:17:56 UTC (rev 3575)
@@ -139,6 +139,7 @@
 				m.put("version", mi.version);
 				m.put("delta", mi.delta);
 				m.put("cipherKey", mi.cipherKey);
+				m.put("features", new JSONArray(mi.features));
 				r.put(m);
 			}
 			callbackContext.success(r);
@@ -243,6 +244,7 @@
 				m.put("version", mi.version);
 				m.put("delta", mi.delta);
 				m.put("cipherKey", mi.cipherKey);
+				m.put("features", new JSONArray(mi.features));
 				r.put(m);
 			}
 			callbackContext.success(r);
@@ -357,13 +359,16 @@
 			result.setKeepCallback(true);
 			callbackContext.sendPluginResult(result);
 		}
-		else if (action.equals("SWMgr_registerBibleSyncListener")) {
+		else if (action.equals("SWMgr_startBibleSync")) {
 			final CallbackContext bibleSyncListener = callbackContext;
+			final String appName = args.getString(0);
+			final String userName = args.getString(1);
+			final String passphrase = args.getString(2);
 
 			cordova.getThreadPool().execute(new Runnable() {
 			    @Override
 			    public void run() {
-				mgr.registerBibleSyncListener(new SWMgr.BibleSyncListener() {
+				mgr.startBibleSync(appName, userName, passphrase, new SWMgr.BibleSyncListener() {
 					public void messageReceived(String message) {
 						PluginResult result = new PluginResult(PluginResult.Status.OK, message);
 						result.setKeepCallback(true);
@@ -377,6 +382,10 @@
 			result.setKeepCallback(true);
 			callbackContext.sendPluginResult(result);
 		}
+		else if (action.equals("SWMgr_stopBibleSync")) {
+			mgr.stopBibleSync();
+			callbackContext.success();
+		}
 		else if (action.equals("SWMgr_setJavascript")) {
 			boolean val = args.getBoolean(0);
 			mgr.setJavascript(val);

Modified: trunk/bindings/cordova/org.crosswire.sword.cordova.SWORD/www/SWORD.js
===================================================================
--- trunk/bindings/cordova/org.crosswire.sword.cordova.SWORD/www/SWORD.js	2018-03-11 21:59:28 UTC (rev 3574)
+++ trunk/bindings/cordova/org.crosswire.sword.cordova.SWORD/www/SWORD.js	2018-03-25 13:17:56 UTC (rev 3575)
@@ -315,13 +315,20 @@
 	return retVal;
 }
 
-SWMgr.prototype.registerBibleSyncListener = function(callback) {
+SWMgr.prototype.startBibleSync = function(appName, userName, passphrase, callback) {
 	exec(callback,
 		function(err) { utils.alert('[ERROR] problem: ' + err); },
-		"SWORD", "SWMgr_registerBibleSyncListener", []
+		"SWORD", "SWMgr_startBibleSync", [appName, userName, passphrase]
 	);
 }
 
+SWMgr.prototype.stopBibleSync = function() {
+	exec(function() {},
+		function(err) { utils.alert('[ERROR] problem: ' + err); },
+		"SWORD", "SWMgr_stopBibleSync", []
+	);
+}
+
 SWMgr.prototype.sendBibleSyncMessage = function(osisRef, callback) {
 	exec(callback?callback:function() {},
 		function(err) { utils.alert('[ERROR] problem: ' + err); },

Modified: trunk/bindings/java-jni/jni/swordstub.cpp
===================================================================
--- trunk/bindings/java-jni/jni/swordstub.cpp	2018-03-11 21:59:28 UTC (rev 3574)
+++ trunk/bindings/java-jni/jni/swordstub.cpp	2018-03-25 13:17:56 UTC (rev 3575)
@@ -262,21 +262,9 @@
 }
 #endif
 
-
-static void initBibleSync() {
-#ifdef BIBLESYNC
-	if (!bibleSync) {
-SWLog::getSystemLog()->logDebug("bibleSync initializing c-tor");
-		bibleSync = new BibleSync("SWORD", (const char *)SWVersion().currentVersion, "SwordUser");
-SWLog::getSystemLog()->logDebug("bibleSync initializing setMode");
-		bibleSync->setMode(BSP_MODE_PERSONAL, bibleSyncCallback, "passphrase");
-	}
-#endif
 }
 
-}
 
-
 JNIEXPORT jstring JNICALL Java_org_crosswire_android_sword_SWMgr_version
 		(JNIEnv *env, jobject me) {
 
@@ -301,6 +289,7 @@
 
 	const char *basePath = (basePathJS?env->GetStringUTFChars(basePathJS, NULL):0);
 	STORAGE_BASE = basePath;
+	env->ReleaseStringUTFChars(basePathJS, basePath);
 	SWLog::getSystemLog()->logDebug("setting STORAGE_BASE to: %s", STORAGE_BASE.c_str());
 
 	delete mgr;
@@ -339,6 +328,8 @@
 SWLog::getSystemLog()->logDebug("getModInfoList returning %d length array\n", size);
 
 	jclass clazzModInfo = env->FindClass("org/crosswire/android/sword/SWMgr$ModInfo");
+	jclass clazzString  = env->FindClass("java/lang/String");
+
 	jfieldID nameID     = env->GetFieldID(clazzModInfo, "name",        "Ljava/lang/String;");
 	jfieldID descID     = env->GetFieldID(clazzModInfo, "description", "Ljava/lang/String;");
 	jfieldID catID      = env->GetFieldID(clazzModInfo, "category",    "Ljava/lang/String;");
@@ -346,6 +337,7 @@
 	jfieldID versionID  = env->GetFieldID(clazzModInfo, "version",     "Ljava/lang/String;");
 	jfieldID deltaID    = env->GetFieldID(clazzModInfo, "delta",       "Ljava/lang/String;");
 	jfieldID cipherKeyID= env->GetFieldID(clazzModInfo, "cipherKey",   "Ljava/lang/String;");
+	jfieldID featuresID = env->GetFieldID(clazzModInfo, "features",    "[Ljava/lang/String;");
 
 	jobjectArray ret = (jobjectArray) env->NewObjectArray(size, clazzModInfo, NULL);
 
@@ -353,32 +345,45 @@
 	for (sword::ModMap::iterator it = mgr->Modules.begin(); it != mgr->Modules.end(); ++it) {
 		SWModule *module = it->second;
 
-//		if ((!(module->getConfigEntry("CipherKey"))) || (*(module->getConfigEntry("CipherKey")))) {
-			SWBuf type = module->getType();
-			SWBuf cat = module->getConfigEntry("Category");
-			SWBuf version = module->getConfigEntry("Version");
-			if (cat.length() > 0) type = cat;
+		SWBuf type = module->getType();
+		SWBuf cat = module->getConfigEntry("Category");
+		SWBuf version = module->getConfigEntry("Version");
+		if (cat.length() > 0) type = cat;
 
-			jobject modInfo = env->AllocObject(clazzModInfo); 
+		jobject modInfo = env->AllocObject(clazzModInfo); 
 
-			jstring val;
-			val = env->NewStringUTF(assureValidUTF8(module->getName()));        env->SetObjectField(modInfo, nameID     , val); env->DeleteLocalRef(val);
-			val = env->NewStringUTF(assureValidUTF8(module->getDescription())); env->SetObjectField(modInfo, descID     , val); env->DeleteLocalRef(val);
-			val = env->NewStringUTF(assureValidUTF8(type.c_str()));             env->SetObjectField(modInfo, catID      , val); env->DeleteLocalRef(val);
-			val = env->NewStringUTF(assureValidUTF8(module->getLanguage()));    env->SetObjectField(modInfo, langID     , val); env->DeleteLocalRef(val);
-			val = env->NewStringUTF(assureValidUTF8(version.c_str()));          env->SetObjectField(modInfo, versionID  , val); env->DeleteLocalRef(val);
-			val = env->NewStringUTF(assureValidUTF8(""));                       env->SetObjectField(modInfo, deltaID    , val); env->DeleteLocalRef(val);
-			const char *cipherKey = module->getConfigEntry("CipherKey");
-			if (cipherKey) {
-				val = env->NewStringUTF(assureValidUTF8(cipherKey));        env->SetObjectField(modInfo, cipherKeyID, val); env->DeleteLocalRef(val);
-			}
-			else                                                                env->SetObjectField(modInfo, cipherKeyID, NULL);
+		jstring val;
+		val = env->NewStringUTF(assureValidUTF8(module->getName()));        env->SetObjectField(modInfo, nameID     , val); env->DeleteLocalRef(val);
+		val = env->NewStringUTF(assureValidUTF8(module->getDescription())); env->SetObjectField(modInfo, descID     , val); env->DeleteLocalRef(val);
+		val = env->NewStringUTF(assureValidUTF8(type.c_str()));             env->SetObjectField(modInfo, catID      , val); env->DeleteLocalRef(val);
+		val = env->NewStringUTF(assureValidUTF8(module->getLanguage()));    env->SetObjectField(modInfo, langID     , val); env->DeleteLocalRef(val);
+		val = env->NewStringUTF(assureValidUTF8(version.c_str()));          env->SetObjectField(modInfo, versionID  , val); env->DeleteLocalRef(val);
+		val = env->NewStringUTF(assureValidUTF8(""));                       env->SetObjectField(modInfo, deltaID    , val); env->DeleteLocalRef(val);
+		const char *cipherKey = module->getConfigEntry("CipherKey");
+		if (cipherKey) {
+			val = env->NewStringUTF(assureValidUTF8(cipherKey));        env->SetObjectField(modInfo, cipherKeyID, val); env->DeleteLocalRef(val);
+		}
+		else                                                                env->SetObjectField(modInfo, cipherKeyID, NULL);
 
-			env->SetObjectArrayElement(ret, i++, modInfo);
+		ConfigEntMap::const_iterator start = module->getConfig().lower_bound("Feature");
+		ConfigEntMap::const_iterator end   = module->getConfig().upper_bound("Feature");
 
-			env->DeleteLocalRef(modInfo);
+		int featureCount = 0;
+		for (ConfigEntMap::const_iterator it = start; it != end; ++it) {
+			++featureCount;
+		}
+		jobjectArray features = (jobjectArray) env->NewObjectArray(featureCount, clazzString, NULL);
+		featureCount = 0;
+		for (ConfigEntMap::const_iterator it = start; it != end; ++it) {
+			env->SetObjectArrayElement(features, featureCount++, env->NewStringUTF(assureValidUTF8(it->second)));
+		}
+		env->SetObjectField(modInfo, featuresID, features);
+		env->DeleteLocalRef(features);
 
-//		}
+		env->SetObjectArrayElement(ret, i++, modInfo);
+
+		env->DeleteLocalRef(modInfo);
+
 	}
 	return ret;
 }
@@ -1756,6 +1761,8 @@
 SWLog::getSystemLog()->logDebug("sourceName: %s\n", sourceName);
 
 	jclass clazzModInfo = env->FindClass("org/crosswire/android/sword/SWMgr$ModInfo");
+	jclass clazzString  = env->FindClass("java/lang/String");
+
 	jfieldID nameID     = env->GetFieldID(clazzModInfo, "name",        "Ljava/lang/String;");
 	jfieldID descID     = env->GetFieldID(clazzModInfo, "description", "Ljava/lang/String;");
 	jfieldID catID      = env->GetFieldID(clazzModInfo, "category",    "Ljava/lang/String;");
@@ -1763,6 +1770,7 @@
 	jfieldID versionID  = env->GetFieldID(clazzModInfo, "version",     "Ljava/lang/String;");
 	jfieldID deltaID    = env->GetFieldID(clazzModInfo, "delta",       "Ljava/lang/String;");
 	jfieldID cipherKeyID= env->GetFieldID(clazzModInfo, "cipherKey",   "Ljava/lang/String;");
+	jfieldID featuresID = env->GetFieldID(clazzModInfo, "features",    "[Ljava/lang/String;");
 
 	InstallSourceMap::iterator source = installMgr->sources.find(sourceName);
 	if (source == installMgr->sources.end()) {
@@ -1810,6 +1818,21 @@
 		}
 		else                                                                env->SetObjectField(modInfo, cipherKeyID, NULL);
 
+		ConfigEntMap::const_iterator start = module->getConfig().lower_bound("Feature");
+		ConfigEntMap::const_iterator end   = module->getConfig().upper_bound("Feature");
+
+		int featureCount = 0;
+		for (ConfigEntMap::const_iterator it = start; it != end; ++it) {
+			++featureCount;
+		}
+		jobjectArray features = (jobjectArray) env->NewObjectArray(featureCount, clazzString, NULL);
+		featureCount = 0;
+		for (ConfigEntMap::const_iterator it = start; it != end; ++it) {
+			env->SetObjectArrayElement(features, featureCount++, env->NewStringUTF(assureValidUTF8(it->second)));
+		}
+		env->SetObjectField(modInfo, featuresID, features);
+		env->DeleteLocalRef(features);
+
 		env->SetObjectArrayElement(ret, i++, modInfo);
 
 		env->DeleteLocalRef(modInfo);
@@ -1942,41 +1965,101 @@
 		(JNIEnv *env, jobject me, jstring osisRefJS) {
 SWLog::getSystemLog()->logDebug("libsword: sendBibleSyncMessage() begin");
 
-	initBibleSync();
-	const char *osisRef = env->GetStringUTFChars(osisRefJS, NULL);
+	if (!bibleSync) {
+SWLog::getSystemLog()->logDebug("libsword: sendBibleSyncMessage() bibleSync not active; message not sent.");
+		return;
+	}
+	const char *osisRefString = env->GetStringUTFChars(osisRefJS, NULL);
+	SWBuf modName = "Bible";
+	SWBuf osisRef = osisRefString;
+	const char *modNamePrefix = osisRef.stripPrefix(':');
+	if (modNamePrefix) modName = modNamePrefix;
 
 #ifdef BIBLESYNC
-	BibleSync_xmit_status result = bibleSync->Transmit(BSP_SYNC, "Bible", osisRef);
+	BibleSync_xmit_status result = bibleSync->Transmit(BSP_SYNC, modName.c_str(), osisRef.c_str());
 #endif
 SWLog::getSystemLog()->logDebug("libsword: sendBibleSyncMessage() finished with status code: %d", result);
 
-	env->ReleaseStringUTFChars(osisRefJS, osisRef);
+	env->ReleaseStringUTFChars(osisRefJS, osisRefString);
 }
 
 
 /*
  * NOTE: this method blocks and should be called in a new thread
  * Class:     org_crosswire_android_sword_SWMgr
- * Method:    registerBibleSyncListener
- * Signature: (Ljava/lang/Object;)V
+ * Method:    startBibleSync
+ * Signature: (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lorg/crosswire/android/sword/SWMgr/BibleSyncListener;)V
  */
-JNIEXPORT void JNICALL Java_org_crosswire_android_sword_SWMgr_registerBibleSyncListener
-		(JNIEnv *env, jobject me, jobject bibleSyncListener) {
+JNIEXPORT void JNICALL Java_org_crosswire_android_sword_SWMgr_startBibleSync
+  (JNIEnv *env, jobject me, jstring appNameJS, jstring userNameJS, jstring passphraseJS, jobject bibleSyncListener) {
 
-SWLog::getSystemLog()->logDebug("registerBibleSyncListener() start");
+	SWLog::getSystemLog()->logDebug("startBibleSync() start");
+	// only one thread
+	static bool starting = false;
+	if (starting) return;
+	starting = true;
+	// kill any previous loop
+	if (::bibleSyncListener) bibleSyncListener = 0;
 #ifdef BIBLESYNC
+	const char *paramString = env->GetStringUTFChars(appNameJS, NULL);
+	SWBuf appName = paramString;
+	env->ReleaseStringUTFChars(appNameJS, paramString);
+	paramString = env->GetStringUTFChars(userNameJS, NULL);
+	SWBuf userName = paramString;
+	env->ReleaseStringUTFChars(userNameJS, paramString);
+	paramString = env->GetStringUTFChars(passphraseJS, NULL);
+	SWBuf passphrase = paramString;
+	env->ReleaseStringUTFChars(passphraseJS, paramString);
+
+	// in case we're restarting, wait for our loop to finish for sure
+	if (::bibleSync) {
+SWLog::getSystemLog()->logDebug("startBibleSync() sleeping 3 seconds");
+		sleep(3);
+	}
+
 	::bibleSyncListener = bibleSyncListener;
 	::bibleSyncListenerEnv = env;
-SWLog::getSystemLog()->logDebug("registerBibleSyncListener - calling init");
-	initBibleSync();
-SWLog::getSystemLog()->logDebug("registerBibleSyncListener - starting while listener");
+	SWLog::getSystemLog()->logDebug("startBibleSync - calling init");
+
+	if (!bibleSync) {
+SWLog::getSystemLog()->logDebug("bibleSync initializing c-tor");
+		bibleSync = new BibleSync(appName.c_str(), (const char *)SWVersion().currentVersion, userName.c_str());
+SWLog::getSystemLog()->logDebug("bibleSync initializing setMode");
+		bibleSync->setMode(BSP_MODE_PERSONAL, bibleSyncCallback, passphrase.c_str());
+	}
+	SWLog::getSystemLog()->logDebug("startBibleSync - starting while listener");
+	starting = false;
 	while(::bibleSyncListener) {
-SWLog::getSystemLog()->logDebug("bibleSyncListener - while loop iteration");
+		SWLog::getSystemLog()->logDebug("bibleSyncListener - while loop iteration");
 		BibleSync::Receive(bibleSync);
-SWLog::getSystemLog()->logDebug("bibleSyncListener - sleeping for 2 seconds");
+		SWLog::getSystemLog()->logDebug("bibleSyncListener - sleeping for 2 seconds");
 		sleep(2);
 	}
+	delete bibleSync;
+	bibleSync = 0;
 #else
+	SWLog::getSystemLog()->logDebug("registerBibleSyncListener: !!! BibleSync disabled in native code.");
+#endif
+}
+
+
+/*
+ * Class:     org_crosswire_android_sword_SWMgr
+ * Method:    stopBibleSync
+ * Signature: (V;)V
+ */
+JNIEXPORT void JNICALL Java_org_crosswire_android_sword_SWMgr_stopBibleSync
+		(JNIEnv *env, jobject me) {
+
+SWLog::getSystemLog()->logDebug("stopBibleSync()");
+#ifdef BIBLESYNC
+	// if we have a listen loop going, just break the loop; the bibleSync cleanup will happen there
+	if (::bibleSyncListener) ::bibleSyncListener = 0;
+	else if (bibleSync) {
+		delete bibleSync;
+		bibleSync = 0;
+	}
+#else
 SWLog::getSystemLog()->logDebug("registerBibleSyncListener: !!! BibleSync disabled in native code.");
 #endif
 }

Modified: trunk/bindings/java-jni/src/org/crosswire/android/sword/SWMgr.java
===================================================================
--- trunk/bindings/java-jni/src/org/crosswire/android/sword/SWMgr.java	2018-03-11 21:59:28 UTC (rev 3574)
+++ trunk/bindings/java-jni/src/org/crosswire/android/sword/SWMgr.java	2018-03-25 13:17:56 UTC (rev 3575)
@@ -36,6 +36,7 @@
 		public String version;
 		public String delta;
 		public String cipherKey;
+		public String[] features;
 	}
 
 	public SWMgr() {
@@ -75,11 +76,6 @@
 	public native String[]    getExtraConfigKeys(String section);
 	public native String      getExtraConfigValue(String section, String key);
 
-	public static interface BibleSyncListener {
-		public void messageReceived(String osisRef);
-	}
-	public native void        sendBibleSyncMessage(String osisRef);
-	public native void        registerBibleSyncListener(BibleSyncListener listener);
 	public String             getStorageBasePath() {
 		return ".";
 /*
@@ -87,6 +83,12 @@
 		return context.getFilesDir().getAbsolutePath();
 */
 	}
+	public static interface BibleSyncListener {
+		public void messageReceived(String osisRef);
+	}
+	public native void        startBibleSync(String appName, String userName, String passphrase, BibleSyncListener listener);
+	public native void        stopBibleSync();
+	public native void        sendBibleSyncMessage(String osisRef);
 }
 
 




More information about the sword-cvs mailing list