void JPlugin::fetchFinished(QNetworkReply* reply) { reply->deleteLater(); if (!m_fetchCallbacks.contains(reply)) return; // The transfer has been stopped JObject& iface = m_fetchCallbacks[reply].second; try { if (reply->error() != QNetworkReply::NoError) { if (m_transfer) m_transfer->logMessage(QLatin1String("JPlugin::fetchFinished(): ")+reply->errorString()); iface.call("onFailed", JSignature().addString(), reply->errorString()); } else { QByteArray qbuf = reply->readAll(); JByteBuffer buf (qbuf.data(), qbuf.size()); QList<QByteArray> list = reply->rawHeaderList(); JMap map(list.size()); foreach (QByteArray ba, list) { QString k, v; k = QString(ba).toLower(); v = QString(reply->rawHeader(ba)).trimmed(); qDebug() << "Header:" << k << v; map.put(k, v); } qDebug() << "fetchFinished.onCompleted:" << buf.toString(); if (m_transfer) m_transfer->logMessage(QLatin1String("JPlugin::fetchFinished(): OK")); iface.call("onCompleted", JSignature().add("java.nio.ByteBuffer").add("java.util.Map"), buf, map); } } catch (const JException& e) { if (m_transfer) { m_transfer->setMessage(tr("Java exception: %1").arg(e.what())); m_transfer->setState(Transfer::Failed); } else throw; } m_fetchCallbacks.remove(reply); }
void JavaUpload::changeActive(bool nowActive) { m_buffer.clear(); if (nowActive) { m_file.setFileName(m_strSource); if (!m_file.open(QIODevice::ReadOnly)) { m_strMessage = m_file.errorString(); setState(Failed); return; } // call Java m_plugin->call("processFile", JSignature().addString(), JArgs() << m_strSource); } else { CurlPoller::instance()->removeTransfer(this, true); resetStatistics(); if(m_curl) m_curl = 0; if(m_postData) { curl_formfree(m_postData); m_postData = 0; } m_plugin->abort(); } }
void JavaUpload::checkResponse() { // call Java JByteBuffer direct(m_buffer.data(), m_buffer.size()); JMap hdr = JMap::fromQMap(m_headers); m_plugin->call("checkResponse", JSignature().add("java.nio.ByteBuffer").add("java.util.Map"), JArgs() << direct << hdr); }
void JClass::registerNativeMethods(const QList<JNativeMethod>& m) { if (m.isEmpty()) return; JNINativeMethod* nm = new JNINativeMethod[m.size()]; for (int i = 0; i < m.size(); i++) nm[i] = m[i].toStruct(); JNIEnv* env = *JVM::instance(); env->RegisterNatives(m_class, nm, m.size()); delete [] nm; JObject ex = env->ExceptionOccurred(); if (!ex.isNull()) { env->ExceptionClear(); ex.call("printStackTrace"); QString message = ex.call("getMessage", JSignature().retString()).toString(); QString className = ex.getClass().getClassName(); throw JException(message, className, ex); } }
QString JClass::getClassName() const { JScope s; JObject obj(m_class); QList<QVariant> args; return obj.call("getCanonicalName", JSignature().retString(), args).toString(); }
void JPlugin::registerNatives() { QList<JNativeMethod> natives; natives << JNativeMethod("fetchPage", JSignature().addString().add("info.dolezel.fatrat.plugins.listeners.PageFetchListener").addString().add("java.util.Map"), fetchPage); JClass("info.dolezel.fatrat.plugins.Plugin").registerNativeMethods(natives); }
void JExtractorPlugin::registerNatives() { QList<JNativeMethod> natives; natives << JNativeMethod("finishedExtraction", JSignature().addStringA(), finishedExtraction); JClass("info.dolezel.fatrat.plugins.ExtractorPlugin").registerNativeMethods(natives); }
QMap<QString,QString> JVM::getPackageVersions() { JClass cls("info.dolezel.fatrat.plugins.helpers.NativeHelpers"); JMap map = cls.callStatic("getPackageVersions", JSignature().ret("java.util.Map")).value<JObject>(); QMap<QString,QString> rv; map.toQMap(rv); return rv; }
void JavaExtractor::changeActive(bool nowActive) { if (nowActive) { if (m_strUrl.startsWith("http://") || m_strUrl.startsWith("https://")) m_reply = m_network->get(QNetworkRequest(m_strUrl)); else { logMessage(tr("JavaExtractor: Not an HTTP(S) URI, passing the URI directly to the extension")); m_plugin->call("extractList", JSignature().addString().add("java.nio.ByteBuffer").add("java.util.Map"), m_strUrl, JObject(), JObject()); } } else { if (m_reply) m_reply->abort(); } }
void JSettings::registerNatives() { QList<JNativeMethod> natives; natives << JNativeMethod("setValue", JSignature().addString().addString(), setValueString); natives << JNativeMethod("setValue", JSignature().addString().addLong(), setValueLong); natives << JNativeMethod("setValue", JSignature().addString().addBoolean(), setValueBoolean); natives << JNativeMethod("setValue", JSignature().addString().addDouble(), setValueDouble); natives << JNativeMethod("getValue", JSignature().addString().add("java.lang.Object").ret("java.lang.Object"), getValue); natives << JNativeMethod("getValueArray", JSignature().addString().retA("java.lang.Object"), getValueArray); JClass("info.dolezel.fatrat.plugins.config.Settings").registerNativeMethods(natives); }
int JavaExtractor::acceptable(QString uri, bool, const EngineEntry* e) { qDebug() << "JavaExtractor::acceptable():" << uri << e->shortName; assert(m_engines.contains(e->shortName)); JavaEngine& en = m_engines[e->shortName]; if (!en.ownAcceptable.isNull()) { try { return en.ownAcceptable.call("acceptable", JSignature().addString().retInt(), JArgs() << uri).toInt(); } catch (RuntimeException& e) { Logger::global()->enterLogMessage("JavaExtractor", QString("%1 threw an exception in acceptable(): %2") .arg(QString::fromStdString(en.name)).arg(e.what())); } } else if (en.regexp.exactMatch(uri)) return 3; return 0; }
void JavaUpload::globalInit() { if (!JVM::JVMAvailable()) return; // locate Java plugins try { JUploadPlugin::registerNatives(); JClass helper("info.dolezel.fatrat.plugins.helpers.NativeHelpers"); JClass annotation("info.dolezel.fatrat.plugins.annotations.UploadPluginInfo"); JClass annConfigDialog("info.dolezel.fatrat.plugins.annotations.ConfigDialog"); QList<QVariant> args; args << "info.dolezel.fatrat.plugins" << annotation.toVariant(); JArray arr = helper.callStatic("findAnnotatedClasses", JSignature().addString().add("java.lang.Class").retA("java.lang.Class"), args).value<JArray>(); qDebug() << "Found" << arr.size() << "annotated classes (UploadPluginInfo)"; int classes = arr.size(); for (int i = 0; i < classes; i++) { try { JClass obj = (jobject) arr.getObject(i); JObject ann = obj.getAnnotation(annotation); QString name = ann.call("name", JSignature().retString()).toString(); QString clsName = obj.getClassName(); JObject instance(obj, JSignature()); qDebug() << "Class name:" << clsName; qDebug() << "Name:" << name; JObject cfgDlg = obj.getAnnotation(annConfigDialog); JavaEngine e = { "EXT - " + name.toStdString(), clsName.toStdString() }; if (!cfgDlg.isNull()) e.configDialog = cfgDlg.call("value", JSignature().retString()).toString(); if (instance.instanceOf("info.dolezel.fatrat.plugins.extra.URLAcceptableFilter")) e.ownAcceptable = instance; if (instance.instanceOf("info.dolezel.fatrat.plugins.listeners.ConfigListener")) g_configListeners << instance; m_engines[clsName] = e; qDebug() << "createInstance of " << clsName; EngineEntry entry; entry.longName = m_engines[clsName].name.c_str(); entry.shortName = m_engines[clsName].shortName.c_str(); entry.lpfnAcceptable2 = JavaUpload::acceptable; entry.lpfnCreate2 = JavaUpload::createInstance; entry.lpfnInit = 0; entry.lpfnExit = 0; entry.lpfnMultiOptions = 0; addTransferClass(entry, Transfer::Upload); } catch (const RuntimeException& e) { qDebug() << e.what(); } } } catch (const RuntimeException& e) { qDebug() << e.what(); } }
void JavaExtractor::globalInit() { try { JClass helper("info.dolezel.fatrat.plugins.helpers.NativeHelpers"); JClass annotation("info.dolezel.fatrat.plugins.annotations.ExtractorPluginInfo"); JExtractorPlugin::registerNatives(); JArgs args; args << "info.dolezel.fatrat.plugins" << annotation.toVariant(); JArray arr = helper.callStatic("findAnnotatedClasses", JSignature().addString().add("java.lang.Class").retA("java.lang.Class"), args).value<JArray>(); qDebug() << "Found" << arr.size() << "annotated classes (ExtractorPluginInfo)"; int classes = arr.size(); for (int i = 0; i < classes; i++) { try { JClass obj = (jobject) arr.getObject(i); JObject ann = obj.getAnnotation(annotation); QString regexp = ann.call("regexp", JSignature().retString()).toString(); QString name = ann.call("name", JSignature().retString()).toString(); QString targetClassName = ann.call("transferClassName", JSignature().retString()).toString(); QString clsName = obj.getClassName(); JObject instance(obj, JSignature()); if (targetClassName.isEmpty()) { JClass cls = JClass(ann.call("transferClass", JSignature().ret("java.lang.Class")).value<JObject>()); if (!cls.isNull() && cls.getClassName() != "java.lang.Object") targetClassName = cls.getClassName(); } qDebug() << "Class name:" << clsName; qDebug() << "Name:" << name; qDebug() << "Regexp:" << regexp; JavaEngine e = { "EXT - " + name.toStdString(), clsName.toStdString(), QRegExp(regexp) }; if (instance.instanceOf("info.dolezel.fatrat.plugins.extra.URLAcceptableFilter")) e.ownAcceptable = instance; if (instance.instanceOf("info.dolezel.fatrat.plugins.listeners.ConfigListener")) g_configListeners << instance; e.targetClass = targetClassName; m_engines[clsName] = e; EngineEntry entry; entry.longName = m_engines[clsName].name.c_str(); entry.shortName = m_engines[clsName].shortName.c_str(); entry.lpfnAcceptable2 = JavaExtractor::acceptable; entry.lpfnCreate2 = JavaExtractor::createInstance; entry.lpfnInit = 0; entry.lpfnExit = 0; entry.lpfnMultiOptions = 0; addTransferClass(entry, Transfer::Download); } catch (const RuntimeException& e) { qDebug() << e.what(); } } } catch (const RuntimeException& e) { qDebug() << e.what(); } }
JSignature JSignature::sigA(QString cls) { QString name = "[L" + cls.replace('.', '/')+';'; return JSignature(name); }
JObject JClass::getAnnotation(JClass cls) { return toClassObject().call("getAnnotation", JSignature().add("java.lang.Class").ret("java.lang.annotation.Annotation"), JArgs() << cls.toVariant()).value<JObject>(); }
QVariant JClass::callStatic(const char* name, const char* sig, QList<QVariant> args) { JScope s; JNIEnv* env = *JVM::instance(); jmethodID mid = env->GetStaticMethodID(m_class, name, sig); if (!mid) throw RuntimeException(QObject::tr("Method %1 %2 not found").arg(name).arg(sig)); JValue vals[args.size()]; jvalue jargs[args.size()]; for(int i=0;i<args.size();i++) { vals[i] = variantToValue(args[i]); jargs[i] = vals[i]; } const char* rvtype = strchr(sig, ')'); if (!rvtype) throw RuntimeException(QObject::tr("Invalid method return type").arg(name).arg(sig)); rvtype++; QVariant retval; switch (*rvtype) { case 'V': env->CallStaticVoidMethodA(m_class, mid, jargs); break; case '[': { jobject obj = env->CallStaticObjectMethodA(m_class, mid, jargs); retval.setValue<JArray>(JArray(obj)); break; } case 'L': { jclass string_class = env->FindClass("java/lang/String"); jobject obj = env->CallStaticObjectMethodA(m_class, mid, jargs); if (obj && env->IsInstanceOf(obj, string_class) && !strcmp(rvtype+1, "java/lang/String;")) retval = JString(jstring(obj)).str(); else { QVariant var; var.setValue<JObject>(JObject(obj)); retval = var; } break; } case 'Z': retval = (bool) env->CallStaticBooleanMethodA(m_class, mid, jargs); break; case 'B': retval = env->CallStaticByteMethodA(m_class, mid, jargs); break; case 'C': retval = env->CallStaticCharMethodA(m_class, mid, jargs); break; case 'S': retval = env->CallStaticShortMethodA(m_class, mid, jargs); break; case 'I': retval = env->CallStaticIntMethodA(m_class, mid, jargs); break; case 'J': retval = (qlonglong) env->CallStaticLongMethodA(m_class, mid, jargs); break; case 'F': retval = env->CallStaticFloatMethodA(m_class, mid, jargs); break; case 'D': retval = env->CallStaticDoubleMethodA(m_class, mid, jargs); break; default: throw RuntimeException(QObject::tr("Unknown Java data type: %1").arg(*rvtype)); } JObject ex = env->ExceptionOccurred(); if (!ex.isNull()) { env->ExceptionClear(); ex.call("printStackTrace"); QString message = ex.call("getMessage", JSignature().retString()).toString(); QString className = ex.getClass().getClassName(); throw JException(message, className, ex); } return retval; }