From 0b16b2eeae49711c8c698b63b8f4bfa7724114cd Mon Sep 17 00:00:00 2001 From: clay_shooter Date: Wed, 4 Oct 2006 03:18:59 +0000 Subject: [PATCH] SF1570270 Proxy unhook detatched threads. SF1538011 toString() not compliant, large ripple into toXXX() methods SF1478172 Variant jni methods public without protection. Now JNI methods behind java methods --- docs/ReleaseNotes.html | 40 +- jni/EventProxy.cpp | 133 +-- jni/Variant.cpp | 316 ++---- jni/Variant.h | 281 ++--- samples/com/jacob/samples/access/Access.java | 5 +- samples/com/jacob/samples/ado/Command.java | 8 +- samples/com/jacob/samples/ado/Connection.java | 16 +- samples/com/jacob/samples/ado/Field.java | 12 +- samples/com/jacob/samples/ado/Fields.java | 2 +- samples/com/jacob/samples/ado/Recordset.java | 38 +- src/com/jacob/activeX/ActiveXComponent.java | 6 +- src/com/jacob/com/Variant.java | 958 +++++++++++++++--- unittest/com/jacob/com/VariantTest.java | 163 ++- unittest/com/jacob/test/events/IETest.java | 66 +- 14 files changed, 1306 insertions(+), 738 deletions(-) diff --git a/docs/ReleaseNotes.html b/docs/ReleaseNotes.html index 2ee23e2..ff65995 100644 --- a/docs/ReleaseNotes.html +++ b/docs/ReleaseNotes.html @@ -9,6 +9,18 @@
  • Build process now notifies developer if version property missing
  • +
  • + API Changes + +
  • Tracked Changes

    @@ -18,11 +30,31 @@ 1550604 - Build process died with confusing error if version not set in properties file + Build process died with confusing error if version not set in properties file(pre1) SF1511033 - Fix array index out of bounds problem due to coding error + Fix array index out of bounds problem due to coding error (pre1) + + + 1570270 + ~Event method in EventProxy may unhook java thread from VM. + Can get JNI error because unhooking listner detatched Java VM thread (pre1) + + + 1538011 + toString() non compliant with java standards. The toString() method + converted the underlying data to a string and it shouldn't. This caused + a rethinking of all toXXX() methods other than toDispatch(). Most of the + toXXX() methods have now been deprecated and should be replaced with getXXX() methods. + (pre1) + + + 1478162 + Variant does not warn user if methods called after released. + All putXXX() and getXXX() methods now check to see if they've been released + prior to calling the JNI code. toXXX() methods are deprecated but protected + in the same way.(pre1)   @@ -36,7 +68,7 @@ Support command line parameter dll location specification. Applets and other tools can now specificy the dll location that is fed to a System.load() rather than System.loadLibrary for the - situation where the app can't write the dll to a library path directory. + situation where the app can't write the dll to a library path directory.(pre1)   @@ -49,7 +81,7 @@ 1550628 Moved all LoadLibrary requests into JacobObject. Classes not subclassed off of JacobObject make calls to a static method on JacobObject to make sure - DLL is loaded + DLL is loaded(pre1) diff --git a/jni/EventProxy.cpp b/jni/EventProxy.cpp index d31a500..c49bd10 100644 --- a/jni/EventProxy.cpp +++ b/jni/EventProxy.cpp @@ -33,15 +33,14 @@ EventProxy::EventProxy(JNIEnv *env, eventIID(eid), MethNum(mNum), MethName(mName), MethID(mID) { - // don't really need the variant object but we keep a reference - // anyway - javaSinkObj = env->NewGlobalRef(aSinkObj); - if (env->ExceptionOccurred()) { env->ExceptionDescribe(); env->ExceptionClear();} + // keep a pointer to the sink + javaSinkObj = env->NewGlobalRef(aSinkObj); + if (env->ExceptionOccurred()) { env->ExceptionDescribe(); env->ExceptionClear();} // we need this to attach to the event invocation thread - env->GetJavaVM(&jvm); - if (env->ExceptionOccurred()) { env->ExceptionDescribe(); env->ExceptionClear();} - AddRef(); + env->GetJavaVM(&jvm); + if (env->ExceptionOccurred()) { env->ExceptionDescribe(); env->ExceptionClear();} + AddRef(); Connect(env); } @@ -60,24 +59,36 @@ EventProxy::~EventProxy() { JNIEnv *env; Disconnect(); - // attach to the current running thread - #ifdef JNI_VERSION_1_2 - printf("using version 1.2 API\n"); - jvm->AttachCurrentThread((void **)&env, jvm); - #else - printf("not using version 1.2 API\n"); - jvm->AttachCurrentThread((void**)&env, NULL); - #endif + jint vmConnectionStatus = JNI_EVERSION ; + + // attach to the current running thread -- JDK 1.4 jni.h has two param cover for 3 param call + vmConnectionStatus = jvm->GetEnv((void **)&env, JNI_VERSION_1_2); + if (env->ExceptionOccurred()) { env->ExceptionDescribe(); env->ExceptionClear();} + if (vmConnectionStatus == JNI_EDETACHED){ + //printf("Unhook: Attaching to current thread using JNI Version 1.2 (%d)\n",vmConnectionStatus); + jvm->AttachCurrentThread((void **)&env, jvm); + if (env->ExceptionOccurred()) { env->ExceptionDescribe(); env->ExceptionClear();} + } else { + // should really look for JNI_OK versus an error + // started method hooked so no need to attach again + //printf("Unhook: No need to attach because already attached %d\n",vmConnectionStatus); + } - env->DeleteGlobalRef(javaSinkObj); - if (env->ExceptionOccurred()) { env->ExceptionDescribe(); env->ExceptionClear();} - if (MethNum) { - delete [] MethName; - delete [] MethID; - } + env->DeleteGlobalRef(javaSinkObj); + if (env->ExceptionOccurred()) { env->ExceptionDescribe(); env->ExceptionClear();} + if (MethNum) { + delete [] MethName; + delete [] MethID; + } // detach from thread - jvm->DetachCurrentThread(); + if (vmConnectionStatus == JNI_EDETACHED){ + jvm->DetachCurrentThread(); + //printf("Unhook: Detached\n"); + } else { + //printf("Unhook: No need to detatch because attached prior to method\n"); + } + //fflush(stdout); } void EventProxy::Disconnect() { @@ -113,12 +124,9 @@ STDMETHODIMP EventProxy::Invoke(DISPID dispID, REFIID riid, LCID lcid, unsigned short wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr) { - //Visual C++ 6.0 recognized this as an unused variable - //HRESULT hr; - - const char *eventMethodName = NULL; //Sourceforge report 1394001 - JNIEnv *env = NULL; - jobject retObj; + const char *eventMethodName = NULL; //Sourceforge report 1394001 + JNIEnv *env = NULL; + jobject retObj; // map dispID to jmethodID for(int i=0;iAttachCurrentThread((void **)&env, jvm); - #else - jvm->AttachCurrentThread((void**)&env, NULL); - #endif + //printf("Invoke: Attaching to current thread using JNI Version 1.2\n"); + jvm->AttachCurrentThread((void **)&env, jvm); + if (env->ExceptionOccurred()) { env->ExceptionDescribe(); env->ExceptionClear();} if (!eventMethodName) { - ThrowComFail(env, "Event method received was not defined as part of callback interface", -1); // user did not implement this method + printf("Invoke: didn't find method name\n"); + ThrowComFail(env, "Event method received was not defined as part of callback interface", -1); + + // should we detatch before returning?? The old code didn't but I don't see why not. + // jvm->DetachCurrentThread(); return S_OK; } - // find the class of the InvocationHandler jclass javaSinkClass = env->GetObjectClass(javaSinkObj); - if (env->ExceptionOccurred()) { env->ExceptionDescribe(); env->ExceptionClear();} - jmethodID invokeMethod; - invokeMethod = env->GetMethodID(javaSinkClass, "invoke", "(Ljava/lang/String;[Lcom/jacob/com/Variant;)Lcom/jacob/com/Variant;"); + if (env->ExceptionOccurred()) { env->ExceptionDescribe(); env->ExceptionClear();} + //printf("Invoke: Got sink class\n"); + jmethodID invokeMethod; + invokeMethod = env->GetMethodID(javaSinkClass, "invoke", "(Ljava/lang/String;[Lcom/jacob/com/Variant;)Lcom/jacob/com/Variant;"); if (env->ExceptionOccurred()) { env->ExceptionDescribe(); env->ExceptionClear();} jstring eventMethodNameAsString = env->NewStringUTF(eventMethodName); + //printf("Invoke: Got method name\n"); // now do what we need for the variant - jmethodID getVariantMethod = env->GetMethodID(javaSinkClass, "getVariant", "()Lcom/jacob/com/Variant;"); + jmethodID getVariantMethod = env->GetMethodID(javaSinkClass, "getVariant", "()Lcom/jacob/com/Variant;"); if (env->ExceptionOccurred()) { env->ExceptionDescribe(); env->ExceptionClear();} + //printf("Invoke: Found way too getVariant\n"); jobject aVariantObj = env->CallObjectMethod(javaSinkObj, getVariantMethod); if (env->ExceptionOccurred()) { env->ExceptionDescribe(); env->ExceptionClear();} + //printf("Invoke: Made Variant\n"); jclass variantClass = env->GetObjectClass(aVariantObj); if (env->ExceptionOccurred()) { env->ExceptionDescribe(); env->ExceptionClear();} @@ -166,6 +180,7 @@ STDMETHODIMP EventProxy::Invoke(DISPID dispID, REFIID riid, // make an array of them jobjectArray varr = env->NewObjectArray(numVariantParams, variantClass, 0); if (env->ExceptionOccurred()) { env->ExceptionDescribe(); env->ExceptionClear();} + //printf("Invoke: Created Array\n"); int i,j; for(i=numVariantParams-1,j=0;i>=0;i--,j++) { @@ -181,14 +196,16 @@ STDMETHODIMP EventProxy::Invoke(DISPID dispID, REFIID riid, env->DeleteLocalRef(arg); if (env->ExceptionOccurred()) { env->ExceptionDescribe(); env->ExceptionClear();} } - // Set up the return value - jobject ret; + //printf("Invoke: Filled Array\n"); + // Set up the return value + jobject ret; - ret = env->CallObjectMethod(javaSinkObj, invokeMethod, - eventMethodNameAsString, varr); - if (!env->ExceptionOccurred() && ret != NULL) { - VariantCopy(pVarResult, extractVariant(env,ret)); - } + ret = env->CallObjectMethod(javaSinkObj, invokeMethod, + eventMethodNameAsString, varr); + //printf("Invoke: Invoked callback\n"); + if (!env->ExceptionOccurred() && ret != NULL) { + VariantCopy(pVarResult, extractVariant(env,ret)); + } if (env->ExceptionOccurred()) { env->ExceptionDescribe(); env->ExceptionClear();} // don't need the first variant we created to get the class env->DeleteLocalRef(aVariantObj); @@ -197,17 +214,19 @@ STDMETHODIMP EventProxy::Invoke(DISPID dispID, REFIID riid, // Begin code from Jiffie team that copies parameters back from java to COM for(i=numVariantParams-1,j=0;i>=0;i--,j++) { - jobject arg = env->GetObjectArrayElement(varr, j); - VARIANT *java = extractVariant(env, arg); - VARIANT *com = &pDispParams->rgvarg[i]; - convertJavaVariant(java, com); - zeroVariant(env, arg); - env->DeleteLocalRef(arg); - } - // End code from Jiffie team that copies parameters back from java to COM - // detach from thread - jvm->DetachCurrentThread(); - return S_OK; + jobject arg = env->GetObjectArrayElement(varr, j); + VARIANT *java = extractVariant(env, arg); + VARIANT *com = &pDispParams->rgvarg[i]; + convertJavaVariant(java, com); + zeroVariant(env, arg); + env->DeleteLocalRef(arg); + } + // End code from Jiffie team that copies parameters back from java to COM + // detach from thread + //printf("Invoke: Detatching\n"); + jvm->DetachCurrentThread(); + //fflush(stdout); + return S_OK; } return E_NOINTERFACE; } diff --git a/jni/Variant.cpp b/jni/Variant.cpp index 76c2dfe..90c48b1 100644 --- a/jni/Variant.cpp +++ b/jni/Variant.cpp @@ -155,61 +155,6 @@ JNIEXPORT void JNICALL Java_com_jacob_com_Variant_SerializationReadFromBytes } } -/** - * Converts the data to a Int object and then returns it as a Dispatch - */ - -JNIEXPORT jint JNICALL Java_com_jacob_com_Variant_toInt - (JNIEnv *env, jobject _this) -{ - VARIANT *v = extractVariant(env, _this); - if (v) { - HRESULT hr; - if (FAILED(hr = VariantChangeType(v, v, 0, VT_I4))) { - ThrowComFail(env, "VariantChangeType failed", hr); - return NULL; - } - return (jint)V_I4(v); - } - return NULL; -} - -/** - * Converts the data to a Date object and then returns it as a Dispatch - */ -JNIEXPORT jdouble JNICALL Java_com_jacob_com_Variant_toDate - (JNIEnv *env, jobject _this) -{ - VARIANT *v = extractVariant(env, _this); - if (v) { - HRESULT hr; - if (FAILED(hr = VariantChangeType(v, v, 0, VT_DATE))) { - ThrowComFail(env, "VariantChangeType failed", hr); - return NULL; - } - return (jdouble)V_DATE(v); - } - return NULL; -} - -/** - * Converts the data to a Boolean object and then returns it as a Dispatch - */ -JNIEXPORT jboolean JNICALL Java_com_jacob_com_Variant_toBoolean - (JNIEnv *env, jobject _this) -{ - VARIANT *v = extractVariant(env, _this); - if (v) { - HRESULT hr; - if (FAILED(hr = VariantChangeType(v, v, 0, VT_BOOL))) { - ThrowComFail(env, "VariantChangeType failed", hr); - return NULL; - } - return (jboolean)V_BOOL(v); - } - return NULL; -} - /** * Converts the data to a Enum Variant object and then returns it as a Dispatch */ @@ -243,7 +188,7 @@ JNIEXPORT jobject JNICALL Java_com_jacob_com_Variant_toEnumVariant return NULL; } -JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putNull +JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putVariantNull (JNIEnv *env, jobject _this) { VARIANT *v = extractVariant(env, _this); @@ -259,44 +204,8 @@ JNIEXPORT jobject JNICALL Java_com_jacob_com_Variant_cloneIndirect return NULL; } -/** - * Converts the data to a Double object and then returns it as a Dispatch - */ -JNIEXPORT jdouble JNICALL Java_com_jacob_com_Variant_toDouble - (JNIEnv *env, jobject _this) -{ - VARIANT *v = extractVariant(env, _this); - if (v) { - HRESULT hr; - if (FAILED(hr = VariantChangeType(v, v, 0, VT_R8))) { - ThrowComFail(env, "VariantChangeType failed", hr); - return NULL; - } - return (jdouble)V_R8(v); - } - return NULL; -} -/** - * Converts the data to a Long object and then returns it as a Dispatch - */ -JNIEXPORT jlong JNICALL Java_com_jacob_com_Variant_toCurrency - (JNIEnv *env, jobject _this) -{ - VARIANT *v = extractVariant(env, _this); - if (v) { - HRESULT hr; - if (FAILED(hr = VariantChangeType(v, v, 0, VT_CY))) { - ThrowComFail(env, "VariantChangeType failed", hr); - return NULL; - } - CY cy = V_CY(v); - return (jlong)cy.int64; - } - return NULL; -} - -JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putShortRef +JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putVariantShortRef (JNIEnv *env, jobject _this, jshort s) { VARIANT *v = extractVariant(env, _this); @@ -309,7 +218,7 @@ JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putShortRef } } -JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putIntRef +JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putVariantIntRef (JNIEnv *env, jobject _this, jint s) { VARIANT *v = extractVariant(env, _this); @@ -322,7 +231,7 @@ JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putIntRef } } -JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putDoubleRef +JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putVariantDoubleRef (JNIEnv *env, jobject _this, jdouble s) { VARIANT *v = extractVariant(env, _this); @@ -334,7 +243,7 @@ JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putDoubleRef } } -JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putDateRef +JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putVariantDateRef (JNIEnv *env, jobject _this, jdouble s) { VARIANT *v = extractVariant(env, _this); @@ -348,7 +257,7 @@ JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putDateRef } // SF 1065533 added unicode support -JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putStringRef +JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putVariantStringRef (JNIEnv *env, jobject _this, jstring s) { VARIANT *v = extractVariant(env, _this); @@ -371,7 +280,7 @@ JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putStringRef env->ReleaseStringChars(s,cStr); } } -JNIEXPORT jshort JNICALL Java_com_jacob_com_Variant_getShortRef +JNIEXPORT jshort JNICALL Java_com_jacob_com_Variant_getVariantShortRef (JNIEnv *env, jobject _this) { VARIANT *v = extractVariant(env, _this); @@ -384,7 +293,7 @@ JNIEXPORT jshort JNICALL Java_com_jacob_com_Variant_getShortRef return NULL; } -JNIEXPORT jint JNICALL Java_com_jacob_com_Variant_getIntRef +JNIEXPORT jint JNICALL Java_com_jacob_com_Variant_getVariantIntRef (JNIEnv *env, jobject _this) { VARIANT *v = extractVariant(env, _this); @@ -397,7 +306,7 @@ JNIEXPORT jint JNICALL Java_com_jacob_com_Variant_getIntRef return NULL; } -JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putShort +JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putVariantShort (JNIEnv *env, jobject _this, jshort s) { VARIANT *v = extractVariant(env, _this); @@ -408,7 +317,7 @@ JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putShort } } -JNIEXPORT jshort JNICALL Java_com_jacob_com_Variant_getShort +JNIEXPORT jshort JNICALL Java_com_jacob_com_Variant_getVariantShort (JNIEnv *env, jobject _this) { VARIANT *v = extractVariant(env, _this); @@ -421,7 +330,7 @@ JNIEXPORT jshort JNICALL Java_com_jacob_com_Variant_getShort return NULL; } -JNIEXPORT jdouble JNICALL Java_com_jacob_com_Variant_getDoubleRef +JNIEXPORT jdouble JNICALL Java_com_jacob_com_Variant_getVariantDoubleRef (JNIEnv *env, jobject _this) { VARIANT *v = extractVariant(env, _this); @@ -434,7 +343,7 @@ JNIEXPORT jdouble JNICALL Java_com_jacob_com_Variant_getDoubleRef return NULL; } -JNIEXPORT jdouble JNICALL Java_com_jacob_com_Variant_getDateRef +JNIEXPORT jdouble JNICALL Java_com_jacob_com_Variant_getVariantDateRef (JNIEnv *env, jobject _this) { VARIANT *v = extractVariant(env, _this); @@ -447,7 +356,7 @@ JNIEXPORT jdouble JNICALL Java_com_jacob_com_Variant_getDateRef return NULL; } -JNIEXPORT jstring JNICALL Java_com_jacob_com_Variant_getStringRef +JNIEXPORT jstring JNICALL Java_com_jacob_com_Variant_getVariantStringRef (JNIEnv *env, jobject _this) { VARIANT *v = extractVariant(env, _this); @@ -462,6 +371,9 @@ JNIEXPORT jstring JNICALL Java_com_jacob_com_Variant_getStringRef return NULL; } +/** + * cover for underlying C VariantClear function + */ JNIEXPORT void JNICALL Java_com_jacob_com_Variant_VariantClear (JNIEnv *env, jobject _this) { @@ -474,7 +386,7 @@ JNIEXPORT void JNICALL Java_com_jacob_com_Variant_VariantClear /** * Converts the data to a Dispatch object and then returns it as a Dispatch */ -JNIEXPORT jobject JNICALL Java_com_jacob_com_Variant_toDispatchObject +JNIEXPORT jobject JNICALL Java_com_jacob_com_Variant_toVariantDispatch (JNIEnv *env, jobject _this) { VARIANT *v = extractVariant(env, _this); @@ -503,42 +415,12 @@ JNIEXPORT jobject JNICALL Java_com_jacob_com_Variant_clone return NULL; } -/** - * Converts the data to a String object and then returns it as a Dispatch - */ -JNIEXPORT jstring JNICALL Java_com_jacob_com_Variant_toString - (JNIEnv *env, jobject _this) -{ - VARIANT *v = extractVariant(env, _this); - if (v) { - switch (V_VT(v)) - { - case VT_EMPTY: - case VT_NULL: - case VT_ERROR: - // causes VariantChangeType to bomb - return env->NewStringUTF("null"); - } - HRESULT hr; - // this actually changes the type of the variant to a String! - if (FAILED(hr = VariantChangeType(v, v, 0, VT_BSTR))) { - // cannot change type to a string - return env->NewStringUTF("???"); - } - // create a returnable string from the converted variant - BSTR bs = V_BSTR(v); - jstring js = env->NewString(bs, SysStringLen(bs)); - return js; - } - return NULL; -} - /** * Returns the value of this int as a Boolea if it is of that type. * Otherwise it will return null (no conversion done) */ -JNIEXPORT jint JNICALL Java_com_jacob_com_Variant_getInt +JNIEXPORT jint JNICALL Java_com_jacob_com_Variant_getVariantInt (JNIEnv *env, jobject _this) { VARIANT *v = extractVariant(env, _this); @@ -556,7 +438,7 @@ JNIEXPORT jint JNICALL Java_com_jacob_com_Variant_getInt * Otherwise it will return null (no conversion done) */ -JNIEXPORT jdouble JNICALL Java_com_jacob_com_Variant_getDate +JNIEXPORT jdouble JNICALL Java_com_jacob_com_Variant_getVariantDate (JNIEnv *env, jobject _this) { VARIANT *v = extractVariant(env, _this); @@ -569,7 +451,7 @@ JNIEXPORT jdouble JNICALL Java_com_jacob_com_Variant_getDate return NULL; } -JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putInt +JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putVariantInt (JNIEnv *env, jobject _this, jint i) { VARIANT *v = extractVariant(env, _this); @@ -580,7 +462,7 @@ JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putInt } } -JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putDate +JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putVariantDate (JNIEnv *env, jobject _this, jdouble date) { VARIANT *v = extractVariant(env, _this); @@ -591,29 +473,11 @@ JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putDate } } -/** - * Converts the data to a Byte object and then returns it as a Dispatch - */ -JNIEXPORT jbyte JNICALL Java_com_jacob_com_Variant_toByte - (JNIEnv *env, jobject _this) -{ - VARIANT *v = extractVariant(env, _this); - if (v) { - HRESULT hr; - if (FAILED(hr = VariantChangeType(v, v, 0, VT_UI1))) { - ThrowComFail(env, "VariantChangeType failed", hr); - return NULL; - } - return (jbyte)V_UI1(v); - } - return NULL; -} - /** * Returns the value of this Variant as a Boolea if it is of that type. * Otherwise it will return null (no conversion done) */ -JNIEXPORT jboolean JNICALL Java_com_jacob_com_Variant_getBoolean +JNIEXPORT jboolean JNICALL Java_com_jacob_com_Variant_getVariantBoolean (JNIEnv *env, jobject _this) { VARIANT *v = extractVariant(env, _this); @@ -630,7 +494,7 @@ JNIEXPORT jboolean JNICALL Java_com_jacob_com_Variant_getBoolean * Returns the value of this Variant as a Byte if it is of that type. * Otherwise it will return null (no conversion done) */ -JNIEXPORT jbyte JNICALL Java_com_jacob_com_Variant_getByte +JNIEXPORT jbyte JNICALL Java_com_jacob_com_Variant_getVariantByte (JNIEnv *env, jobject _this) { VARIANT *v = extractVariant(env, _this); @@ -643,7 +507,7 @@ JNIEXPORT jbyte JNICALL Java_com_jacob_com_Variant_getByte return NULL; } -JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putBoolean +JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putVariantBoolean (JNIEnv *env, jobject _this, jboolean b) { VARIANT *v = extractVariant(env, _this); @@ -652,10 +516,10 @@ JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putBoolean V_VT(v) = VT_BOOL; V_BOOL(v) = b == JNI_TRUE ? VARIANT_TRUE : VARIANT_FALSE; } - else ThrowComFail(env, "putBoolean failed", -1); + else ThrowComFail(env, "putVariantBoolean failed", -1); } -JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putByte +JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putVariantByte (JNIEnv *env, jobject _this, jbyte b) { VARIANT *v = extractVariant(env, _this); @@ -664,25 +528,10 @@ JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putByte V_VT(v) = VT_UI1; V_UI1(v) = b; } - else ThrowComFail(env, "putByte failed", -1); + else ThrowComFail(env, "putVariantByte failed", -1); } -JNIEXPORT jint JNICALL Java_com_jacob_com_Variant_toError - (JNIEnv *env, jobject _this) -{ - VARIANT *v = extractVariant(env, _this); - if (v) { - HRESULT hr; - if (FAILED(hr = VariantChangeType(v, v, 0, VT_ERROR))) { - ThrowComFail(env, "VariantChangeType failed", hr); - return NULL; - } - return (jint)V_ERROR(v); - } - return NULL; -} - -JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putEmpty +JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putVariantEmpty (JNIEnv *env, jobject _this) { VARIANT *v = extractVariant(env, _this); @@ -695,7 +544,7 @@ JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putEmpty /** * Sets the variant type to dispatch with no value object **/ -JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putNothing +JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putVariantNothing (JNIEnv *env, jobject _this) { VARIANT *v = extractVariant(env, _this); @@ -705,7 +554,7 @@ JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putNothing } } -JNIEXPORT jint JNICALL Java_com_jacob_com_Variant_getError +JNIEXPORT jint JNICALL Java_com_jacob_com_Variant_getVariantError (JNIEnv *env, jobject _this) { VARIANT *v = extractVariant(env, _this); @@ -718,7 +567,7 @@ JNIEXPORT jint JNICALL Java_com_jacob_com_Variant_getError return NULL; } -JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putError +JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putVariantError (JNIEnv *env, jobject _this, jint i) { VARIANT *v = extractVariant(env, _this); @@ -734,7 +583,7 @@ JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putError * Returns the value of this Variant as a double if it is of that type. * Otherwise it will return null (no conversion done) */ -JNIEXPORT jdouble JNICALL Java_com_jacob_com_Variant_getDouble +JNIEXPORT jdouble JNICALL Java_com_jacob_com_Variant_getVariantDouble (JNIEnv *env, jobject _this) { VARIANT *v = extractVariant(env, _this); @@ -747,7 +596,7 @@ JNIEXPORT jdouble JNICALL Java_com_jacob_com_Variant_getDouble return NULL; } -JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putCurrency +JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putVariantCurrency (JNIEnv *env, jobject _this, jlong cur) { VARIANT *v = extractVariant(env, _this); @@ -757,7 +606,7 @@ JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putCurrency pf.int64 = (LONGLONG)cur; V_VT(v) = VT_CY; V_CY(v) = pf; - } else ThrowComFail(env, "putCurrency failed", -1); + } else ThrowComFail(env, "putVariantCurrency failed", -1); } /** @@ -765,7 +614,7 @@ JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putCurrency * There is currently no way to pass NULL into this method * to create something like "NOTHING" from VB * */ -JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putDispatchObject +JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putVariantDispatch (JNIEnv *env, jobject _this, jobject _that) { VARIANT *v = extractVariant(env, _this); @@ -779,7 +628,7 @@ JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putDispatchObject } else ThrowComFail(env, "putObject failed", -1); } -JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putDouble +JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putVariantDouble (JNIEnv *env, jobject _this, jdouble d) { VARIANT *v = extractVariant(env, _this); @@ -794,7 +643,7 @@ JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putDouble * Returns the value of this Variant as a long if it is of that type. * Otherwise it will return null (no conversion done) */ -JNIEXPORT jlong JNICALL Java_com_jacob_com_Variant_getCurrency +JNIEXPORT jlong JNICALL Java_com_jacob_com_Variant_getVariantCurrency (JNIEnv *env, jobject _this) { VARIANT *v = extractVariant(env, _this); @@ -812,7 +661,7 @@ JNIEXPORT jlong JNICALL Java_com_jacob_com_Variant_getCurrency } -JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putFloatRef +JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putVariantFloatRef (JNIEnv *env, jobject _this, jfloat val) { VARIANT *v = extractVariant(env, _this); @@ -825,7 +674,7 @@ JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putFloatRef } } -JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putCurrencyRef +JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putVariantCurrencyRef (JNIEnv *env, jobject _this, jlong cur) { VARIANT *v = extractVariant(env, _this); @@ -838,7 +687,7 @@ JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putCurrencyRef } } -JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putErrorRef +JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putVariantErrorRef (JNIEnv *env, jobject _this, jint i) { VARIANT *v = extractVariant(env, _this); @@ -849,7 +698,7 @@ JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putErrorRef } } -JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putBooleanRef +JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putVariantBooleanRef (JNIEnv *env, jobject _this, jboolean b) { VARIANT *v = extractVariant(env, _this); @@ -862,7 +711,7 @@ JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putBooleanRef } } -JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putByteRef +JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putVariantByteRef (JNIEnv *env, jobject _this, jbyte b) { VARIANT *v = extractVariant(env, _this); @@ -879,7 +728,7 @@ JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putByteRef * Returns the value of this Variant as a String if it is of that type. * Otherwise it will return null (no conversion done) */ -JNIEXPORT jstring JNICALL Java_com_jacob_com_Variant_getString +JNIEXPORT jstring JNICALL Java_com_jacob_com_Variant_getVariantString (JNIEnv *env, jobject _this) { VARIANT *v = extractVariant(env, _this); @@ -894,8 +743,10 @@ JNIEXPORT jstring JNICALL Java_com_jacob_com_Variant_getString return NULL; } -// SF 1065533 added unicode support -JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putString +/** + * SF 1065533 added unicode support + * */ +JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putVariantString (JNIEnv *env, jobject _this, jstring s) { VARIANT *v = extractVariant(env, _this); @@ -918,7 +769,7 @@ JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putString } } -JNIEXPORT jfloat JNICALL Java_com_jacob_com_Variant_getFloatRef +JNIEXPORT jfloat JNICALL Java_com_jacob_com_Variant_getVariantFloatRef (JNIEnv *env, jobject _this) { VARIANT *v = extractVariant(env, _this); @@ -931,7 +782,7 @@ JNIEXPORT jfloat JNICALL Java_com_jacob_com_Variant_getFloatRef return NULL; } -JNIEXPORT jlong JNICALL Java_com_jacob_com_Variant_getCurrencyRef +JNIEXPORT jlong JNICALL Java_com_jacob_com_Variant_getVariantCurrencyRef (JNIEnv *env, jobject _this) { VARIANT *v = extractVariant(env, _this); @@ -948,7 +799,7 @@ JNIEXPORT jlong JNICALL Java_com_jacob_com_Variant_getCurrencyRef return NULL; } -JNIEXPORT jint JNICALL Java_com_jacob_com_Variant_getErrorRef +JNIEXPORT jint JNICALL Java_com_jacob_com_Variant_getVariantErrorRef (JNIEnv *env, jobject _this) { VARIANT *v = extractVariant(env, _this); @@ -961,7 +812,7 @@ JNIEXPORT jint JNICALL Java_com_jacob_com_Variant_getErrorRef return NULL; } -JNIEXPORT jboolean JNICALL Java_com_jacob_com_Variant_getBooleanRef +JNIEXPORT jboolean JNICALL Java_com_jacob_com_Variant_getVariantBooleanRef (JNIEnv *env, jobject _this) { VARIANT *v = extractVariant(env, _this); @@ -975,7 +826,7 @@ JNIEXPORT jboolean JNICALL Java_com_jacob_com_Variant_getBooleanRef } -JNIEXPORT jbyte JNICALL Java_com_jacob_com_Variant_getByteRef +JNIEXPORT jbyte JNICALL Java_com_jacob_com_Variant_getVariantByteRef (JNIEnv *env, jobject _this) { VARIANT *v = extractVariant(env, _this); @@ -988,28 +839,10 @@ JNIEXPORT jbyte JNICALL Java_com_jacob_com_Variant_getByteRef return NULL; } -/** - * Converts the data to a Float object and then returns it as a Dispatch - */ -JNIEXPORT jfloat JNICALL Java_com_jacob_com_Variant_toFloat - (JNIEnv *env, jobject _this) -{ - VARIANT *v = extractVariant(env, _this); - if (v) { - HRESULT hr; - if (FAILED(hr = VariantChangeType(v, v, 0, VT_R4))) { - ThrowComFail(env, "VariantChangeType failed", hr); - return NULL; - } - return (jfloat)V_R4(v); - } - return NULL; -} - /** * Converts the data to a Safe Array object and then returns it as a Dispatch */ -JNIEXPORT jobject JNICALL Java_com_jacob_com_Variant_toSafeArray +JNIEXPORT jobject JNICALL Java_com_jacob_com_Variant_toVariantSafeArray (JNIEnv *env, jobject _this, jboolean deepCopy) { VARIANT *v = extractVariant(env, _this); @@ -1031,7 +864,7 @@ JNIEXPORT jobject JNICALL Java_com_jacob_com_Variant_toSafeArray return NULL; } -JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putSafeArrayRef +JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putVariantSafeArrayRef (JNIEnv *env, jobject _this, jobject sa) { SAFEARRAY *psa = extractSA(env, sa); @@ -1054,7 +887,7 @@ JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putSafeArrayRef return; } -JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putSafeArray +JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putVariantSafeArray (JNIEnv *env, jobject _this, jobject sa) { SAFEARRAY *psa = extractSA(env, sa); @@ -1078,7 +911,7 @@ JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putSafeArray /** * sets the type to VT_ERROR and the error message to DISP_E_PARAMNOTFOIUND * */ -JNIEXPORT void JNICALL Java_com_jacob_com_Variant_noParam +JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putVariantNoParam (JNIEnv *env, jobject _this) { VARIANT *v = extractVariant(env, _this); @@ -1092,7 +925,7 @@ JNIEXPORT void JNICALL Java_com_jacob_com_Variant_noParam * Returns the value of this Variant as a Float if it is of that type. * Otherwise it will return null (no conversion done) */ -JNIEXPORT jfloat JNICALL Java_com_jacob_com_Variant_getFloat +JNIEXPORT jfloat JNICALL Java_com_jacob_com_Variant_getVariantFloat (JNIEnv *env, jobject _this) { VARIANT *v = extractVariant(env, _this); @@ -1105,7 +938,7 @@ JNIEXPORT jfloat JNICALL Java_com_jacob_com_Variant_getFloat return NULL; } -JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putFloat +JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putVariantFloat (JNIEnv *env, jobject _this, jfloat val) { VARIANT *v = extractVariant(env, _this); @@ -1119,7 +952,7 @@ JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putFloat /** * changes the type of the underlying variant data * */ -JNIEXPORT void JNICALL Java_com_jacob_com_Variant_changeType +JNIEXPORT void JNICALL Java_com_jacob_com_Variant_changeVariantType (JNIEnv *env, jobject _this, jshort t) { VARIANT *v = extractVariant(env, _this); @@ -1132,7 +965,7 @@ JNIEXPORT void JNICALL Java_com_jacob_com_Variant_changeType * returns the variant type if it is set, otherwise * returns null * */ -JNIEXPORT jshort JNICALL Java_com_jacob_com_Variant_getvt +JNIEXPORT jshort JNICALL Java_com_jacob_com_Variant_getVariantType (JNIEnv *env, jobject _this) { VARIANT *v = extractVariant(env, _this); @@ -1142,39 +975,14 @@ JNIEXPORT jshort JNICALL Java_com_jacob_com_Variant_getvt return NULL; } -/** - * Converts the data to a short object and then returns it as a Dispatch - */ -JNIEXPORT jshort JNICALL Java_com_jacob_com_Variant_toShort - (JNIEnv *env, jobject _this) -{ - VARIANT *v = extractVariant(env, _this); - if (v) { - HRESULT hr; - if (FAILED(hr = VariantChangeType(v, v, 0, VT_I2))) { - ThrowComFail(env, "VariantChangeType failed", hr); - return NULL; - } - return (jshort)V_I2(v); - } - return NULL; -} - -JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putSafeArrayRefHelper - (JNIEnv *env, jobject _this, jint pSA) -{ - VARIANT *v = extractVariant(env, _this); - if (v) { - VariantClear(v); // whatever was there before - } -} +// removed Java_com_jacob_com_Variant_putSafeArrayRefHelper /** * this is a big cover method that returns TRUE if * the variant type is * VT_EMPTY, VT_NULL, VT_ERROR or VT_DISPATCH with no dispatch object * */ -JNIEXPORT jboolean JNICALL Java_com_jacob_com_Variant_isNull +JNIEXPORT jboolean JNICALL Java_com_jacob_com_Variant_isVariantConsideredNull (JNIEnv *env, jobject _this) { VARIANT *v = extractVariant(env, _this); diff --git a/jni/Variant.h b/jni/Variant.h index 5626b90..d7d1149 100644 --- a/jni/Variant.h +++ b/jni/Variant.h @@ -25,29 +25,6 @@ #ifdef __cplusplus extern "C" { #endif -/* - * Class: com_jacob_com_Variant - * Method: toInt - * Signature: ()I - */ -JNIEXPORT jint JNICALL Java_com_jacob_com_Variant_toInt - (JNIEnv *, jobject); - -/* - * Class: com_jacob_com_Variant - * Method: toDate - * Signature: ()D - */ -JNIEXPORT jdouble JNICALL Java_com_jacob_com_Variant_toDate - (JNIEnv *, jobject); - -/* - * Class: com_jacob_com_Variant - * Method: toBoolean - * Signature: ()Z - */ -JNIEXPORT jboolean JNICALL Java_com_jacob_com_Variant_toBoolean - (JNIEnv *, jobject); /* * Class: com_jacob_com_Variant @@ -59,10 +36,10 @@ JNIEXPORT jobject JNICALL Java_com_jacob_com_Variant_toEnumVariant /* * Class: com_jacob_com_Variant - * Method: putNull + * Method: putVariantNull * Signature: ()V */ -JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putNull +JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putVariantNull (JNIEnv *, jobject); /* @@ -75,106 +52,90 @@ JNIEXPORT jobject JNICALL Java_com_jacob_com_Variant_cloneIndirect /* * Class: com_jacob_com_Variant - * Method: toDouble - * Signature: ()D - */ -JNIEXPORT jdouble JNICALL Java_com_jacob_com_Variant_toDouble - (JNIEnv *, jobject); - -/* - * Class: com_jacob_com_Variant - * Method: toCurrency - * Signature: ()J - */ -JNIEXPORT jlong JNICALL Java_com_jacob_com_Variant_toCurrency - (JNIEnv *, jobject); - -/* - * Class: com_jacob_com_Variant - * Method: putShortRef + * Method: putVariantShortRef * Signature: (S)V */ -JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putShortRef +JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putVariantShortRef (JNIEnv *, jobject, jshort); /* * Class: com_jacob_com_Variant - * Method: putIntRef + * Method: putVariantIntRef * Signature: (I)V */ -JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putIntRef +JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putVariantIntRef (JNIEnv *, jobject, jint); /* * Class: com_jacob_com_Variant - * Method: putDoubleRef + * Method: putVariantDoubleRef * Signature: (D)V */ -JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putDoubleRef +JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putVariantDoubleRef (JNIEnv *, jobject, jdouble); /* * Class: com_jacob_com_Variant - * Method: putDateRef + * Method: putVariantDateRef * Signature: (D)V */ -JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putDateRef +JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putVariantDateRef (JNIEnv *, jobject, jdouble); /* * Class: com_jacob_com_Variant - * Method: putStringRef + * Method: putVariantStringRef * Signature: (Ljava/lang/String;)V */ -JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putStringRef +JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putVariantStringRef (JNIEnv *, jobject, jstring); /* * Class: com_jacob_com_Variant - * Method: getShortRef + * Method: getVariantShortRef * Signature: ()S */ -JNIEXPORT jshort JNICALL Java_com_jacob_com_Variant_getShortRef +JNIEXPORT jshort JNICALL Java_com_jacob_com_Variant_getVariantShortRef (JNIEnv *, jobject); /* * Class: com_jacob_com_Variant - * Method: getIntRef + * Method: getVariantIntRef * Signature: ()I */ -JNIEXPORT jint JNICALL Java_com_jacob_com_Variant_getIntRef +JNIEXPORT jint JNICALL Java_com_jacob_com_Variant_getVariantIntRef (JNIEnv *, jobject); /* * Class: com_jacob_com_Variant - * Method: putShort + * Method: putVariantShort * Signature: (S)V */ -JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putShort +JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putVariantShort (JNIEnv *, jobject, jshort); /* * Class: com_jacob_com_Variant - * Method: getShort + * Method: getVariantShort * Signature: ()S */ -JNIEXPORT jshort JNICALL Java_com_jacob_com_Variant_getShort +JNIEXPORT jshort JNICALL Java_com_jacob_com_Variant_getVariantShort (JNIEnv *, jobject); /* * Class: com_jacob_com_Variant - * Method: getDoubleRef + * Method: getVariantDoubleRef * Signature: ()D */ -JNIEXPORT jdouble JNICALL Java_com_jacob_com_Variant_getDoubleRef +JNIEXPORT jdouble JNICALL Java_com_jacob_com_Variant_getVariantDoubleRef (JNIEnv *, jobject); /* * Class: com_jacob_com_Variant - * Method: getDateRef + * Method: getVariantDateRef * Signature: ()D */ -JNIEXPORT jdouble JNICALL Java_com_jacob_com_Variant_getDateRef +JNIEXPORT jdouble JNICALL Java_com_jacob_com_Variant_getVariantDateRef (JNIEnv *, jobject); /* @@ -182,7 +143,7 @@ JNIEXPORT jdouble JNICALL Java_com_jacob_com_Variant_getDateRef * Method: getStringRef * Signature: ()Ljava/lang/String; */ -JNIEXPORT jstring JNICALL Java_com_jacob_com_Variant_getStringRef +JNIEXPORT jstring JNICALL Java_com_jacob_com_Variant_getVariantStringRef (JNIEnv *, jobject); /* @@ -198,7 +159,7 @@ JNIEXPORT void JNICALL Java_com_jacob_com_Variant_com_jacob_com_VariantClear * Method: toDispatch * Signature: ()LDispatch; */ -JNIEXPORT jobject JNICALL Java_com_jacob_com_Variant_toDispatchObject +JNIEXPORT jobject JNICALL Java_com_jacob_com_Variant_toVariantDispatch (JNIEnv *, jobject); /* @@ -211,194 +172,170 @@ JNIEXPORT jobject JNICALL Java_com_jacob_com_Variant_clone /* * Class: com_jacob_com_Variant - * Method: toString - * Signature: ()Ljava/lang/String; - */ -JNIEXPORT jstring JNICALL Java_com_jacob_com_Variant_toString - (JNIEnv *, jobject); - -/* - * Class: com_jacob_com_Variant - * Method: getInt + * Method: getVariantInt * Signature: ()I */ -JNIEXPORT jint JNICALL Java_com_jacob_com_Variant_getInt +JNIEXPORT jint JNICALL Java_com_jacob_com_Variant_getVariantInt (JNIEnv *, jobject); /* * Class: com_jacob_com_Variant - * Method: getDate + * Method: getVariantDate * Signature: ()D */ -JNIEXPORT jdouble JNICALL Java_com_jacob_com_Variant_getDate +JNIEXPORT jdouble JNICALL Java_com_jacob_com_Variant_getVariantDate (JNIEnv *, jobject); /* * Class: com_jacob_com_Variant - * Method: putInt + * Method: putVariantInt * Signature: (I)V */ -JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putInt +JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putVariantInt (JNIEnv *, jobject, jint); /* * Class: com_jacob_com_Variant - * Method: putDate + * Method: putVariantDate * Signature: (D)V */ -JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putDate +JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putVariantDate (JNIEnv *, jobject, jdouble); /* * Class: com_jacob_com_Variant - * Method: toByte - * Signature: ()B - */ -JNIEXPORT jbyte JNICALL Java_com_jacob_com_Variant_toByte - (JNIEnv *, jobject); - -/* - * Class: com_jacob_com_Variant - * Method: getBoolean + * Method: getVariantBoolean * Signature: ()Z */ -JNIEXPORT jboolean JNICALL Java_com_jacob_com_Variant_getBoolean +JNIEXPORT jboolean JNICALL Java_com_jacob_com_Variant_getVariantBoolean (JNIEnv *, jobject); /* * Class: com_jacob_com_Variant - * Method: getByte + * Method: getVariantByte * Signature: ()B */ -JNIEXPORT jbyte JNICALL Java_com_jacob_com_Variant_getByte +JNIEXPORT jbyte JNICALL Java_com_jacob_com_Variant_getVariantByte (JNIEnv *, jobject); /* * Class: com_jacob_com_Variant - * Method: putBoolean + * Method: putVariantBoolean * Signature: (Z)V */ -JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putBoolean +JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putVariantBoolean (JNIEnv *, jobject, jboolean); /* * Class: com_jacob_com_Variant - * Method: putByte + * Method: putVariantByte * Signature: (B)V */ -JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putByte +JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putVariantByte (JNIEnv *, jobject, jbyte); /* * Class: com_jacob_com_Variant - * Method: toError - * Signature: ()I - */ -JNIEXPORT jint JNICALL Java_com_jacob_com_Variant_toError - (JNIEnv *, jobject); - -/* - * Class: com_jacob_com_Variant - * Method: putEmpty + * Method: putVariantEmpty * Signature: ()V */ -JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putEmpty +JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putVariantEmpty (JNIEnv *, jobject); /* * Class: com_jacob_com_Variant - * Method: putEmpty + * Method: putVariantNothing * Signature: ()V */ -JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putNothing +JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putVariantNothing (JNIEnv *, jobject); /* * Class: com_jacob_com_Variant - * Method: getError + * Method: getVariantError * Signature: ()I */ -JNIEXPORT jint JNICALL Java_com_jacob_com_Variant_getError +JNIEXPORT jint JNICALL Java_com_jacob_com_Variant_getVariantError (JNIEnv *, jobject); /* * Class: com_jacob_com_Variant - * Method: putError + * Method: putVariantError * Signature: (I)V */ -JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putError +JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putVariantError (JNIEnv *, jobject, jint); /* * Class: com_jacob_com_Variant - * Method: getDouble + * Method: getVariantDouble * Signature: ()D */ -JNIEXPORT jdouble JNICALL Java_com_jacob_com_Variant_getDouble +JNIEXPORT jdouble JNICALL Java_com_jacob_com_Variant_getVariantDouble (JNIEnv *, jobject); /* * Class: com_jacob_com_Variant - * Method: putCurrency + * Method: putVariantCurrency * Signature: (J)V */ -JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putCurrency +JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putVariantCurrency (JNIEnv *, jobject, jlong); /* * Class: com_jacob_com_Variant - * Method: putObject + * Method: putVariantDispatch * Signature: (Ljava/lang/Object;)V */ -JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putDispatchObject +JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putVariantDispatch (JNIEnv *, jobject, jobject); /* * Class: com_jacob_com_Variant - * Method: putDouble + * Method: putVariantDouble * Signature: (D)V */ -JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putDouble +JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putVariantDouble (JNIEnv *, jobject, jdouble); /* * Class: com_jacob_com_Variant - * Method: getCurrency + * Method: getVariantCurrency * Signature: ()J */ -JNIEXPORT jlong JNICALL Java_com_jacob_com_Variant_getCurrency +JNIEXPORT jlong JNICALL Java_com_jacob_com_Variant_getVariantCurrency (JNIEnv *, jobject); /* * Class: com_jacob_com_Variant - * Method: putFloatRef + * Method: putVariantFloatRef * Signature: (F)V */ -JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putFloatRef +JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putVariantFloatRef (JNIEnv *, jobject, jfloat); /* * Class: com_jacob_com_Variant - * Method: putCurrencyRef + * Method: putVariantCurrencyRef * Signature: (J)V */ -JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putCurrencyRef +JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putVariantCurrencyRef (JNIEnv *, jobject, jlong); /* * Class: com_jacob_com_Variant - * Method: putErrorRef + * Method: putVariantErrorRef * Signature: (I)V */ -JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putErrorRef +JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putVariantErrorRef (JNIEnv *, jobject, jint); /* * Class: com_jacob_com_Variant - * Method: putBooleanRef + * Method: putVariantBooleanRef * Signature: (Z)V */ -JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putBooleanRef +JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putVariantBooleanRef (JNIEnv *, jobject, jboolean); /* @@ -411,10 +348,10 @@ JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putObjectRef /* * Class: com_jacob_com_Variant - * Method: putByteRef + * Method: putVariantByteRef * Signature: (B)V */ -JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putByteRef +JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putVariantByteRef (JNIEnv *, jobject, jbyte); /* @@ -422,135 +359,119 @@ JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putByteRef * Method: getString * Signature: ()Ljava/lang/String; */ -JNIEXPORT jstring JNICALL Java_com_jacob_com_Variant_getString +JNIEXPORT jstring JNICALL Java_com_jacob_com_Variant_getVariantString (JNIEnv *, jobject); /* * Class: com_jacob_com_Variant - * Method: putString + * Method: putVariantString * Signature: (Ljava/lang/String;)V */ -JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putString +JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putVariantString (JNIEnv *, jobject, jstring); /* * Class: com_jacob_com_Variant - * Method: getFloatRef + * Method: getVariantFloatRef * Signature: ()F */ -JNIEXPORT jfloat JNICALL Java_com_jacob_com_Variant_getFloatRef +JNIEXPORT jfloat JNICALL Java_com_jacob_com_Variant_getVariantFloatRef (JNIEnv *, jobject); /* * Class: com_jacob_com_Variant - * Method: getCurrencyRef + * Method: getVariantCurrencyRef * Signature: ()J */ -JNIEXPORT jlong JNICALL Java_com_jacob_com_Variant_getCurrencyRef +JNIEXPORT jlong JNICALL Java_com_jacob_com_Variant_getVariantCurrencyRef (JNIEnv *, jobject); /* * Class: com_jacob_com_Variant - * Method: getErrorRef + * Method: getVariantErrorRef * Signature: ()I */ -JNIEXPORT jint JNICALL Java_com_jacob_com_Variant_getErrorRef +JNIEXPORT jint JNICALL Java_com_jacob_com_Variant_getVariantErrorRef (JNIEnv *, jobject); /* * Class: com_jacob_com_Variant - * Method: getBooleanRef + * Method: getVariantBooleanRef * Signature: ()Z */ -JNIEXPORT jboolean JNICALL Java_com_jacob_com_Variant_getBooleanRef +JNIEXPORT jboolean JNICALL Java_com_jacob_com_Variant_getVariantBooleanRef (JNIEnv *, jobject); /* * Class: com_jacob_com_Variant - * Method: getByteRef + * Method: getVariantByteRef * Signature: ()B */ -JNIEXPORT jbyte JNICALL Java_com_jacob_com_Variant_getByteRef +JNIEXPORT jbyte JNICALL Java_com_jacob_com_Variant_getVariantByteRef (JNIEnv *, jobject); /* * Class: com_jacob_com_Variant - * Method: toFloat - * Signature: ()F - */ -JNIEXPORT jfloat JNICALL Java_com_jacob_com_Variant_toFloat - (JNIEnv *, jobject); - -/* - * Class: com_jacob_com_Variant - * Method: toSafeArray + * Method: toVariantSafeArray * Signature: (Z)Lcom/jacob/com/SafeArray; */ -JNIEXPORT jobject JNICALL Java_com_jacob_com_Variant_toSafeArray +JNIEXPORT jobject JNICALL Java_com_jacob_com_Variant_toVariantSafeArray (JNIEnv *, jobject, jboolean); /* * Class: com_jacob_com_Variant - * Method: putSafeArrayRef + * Method: putVariantSafeArrayRef * Signature: (LSafeArray;)V */ -JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putSafeArrayRef +JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putVariantSafeArrayRef (JNIEnv *, jobject, jobject); /* * Class: com_jacob_com_Variant - * Method: putSafeArray + * Method: putVariantSafeArray * Signature: (LSafeArray;)V */ -JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putSafeArray +JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putVariantSafeArray (JNIEnv *, jobject, jobject); /* * Class: com_jacob_com_Variant - * Method: noParam + * Method: putVariantNoParam * Signature: ()V */ -JNIEXPORT void JNICALL Java_com_jacob_com_Variant_noParam +JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putVariantNoParam (JNIEnv *, jobject); /* * Class: com_jacob_com_Variant - * Method: getFloat + * Method: getVariantFloat * Signature: ()F */ -JNIEXPORT jfloat JNICALL Java_com_jacob_com_Variant_getFloat +JNIEXPORT jfloat JNICALL Java_com_jacob_com_Variant_getVariantFloat (JNIEnv *, jobject); /* * Class: com_jacob_com_Variant - * Method: putFloat + * Method: putVariantFloat * Signature: (F)V */ -JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putFloat +JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putVariantFloat (JNIEnv *, jobject, jfloat); /* * Class: com_jacob_com_Variant - * Method: changeType + * Method: changeVariantType * Signature: (S)V */ -JNIEXPORT void JNICALL Java_com_jacob_com_Variant_changeType +JNIEXPORT void JNICALL Java_com_jacob_com_Variant_changeVariantType (JNIEnv *, jobject, jshort); /* * Class: com_jacob_com_Variant - * Method: getvt + * Method: getVariantType * Signature: ()S */ -JNIEXPORT jshort JNICALL Java_com_jacob_com_Variant_getvt - (JNIEnv *, jobject); - -/* - * Class: com_jacob_com_Variant - * Method: toShort - * Signature: ()S - */ -JNIEXPORT jshort JNICALL Java_com_jacob_com_Variant_toShort +JNIEXPORT jshort JNICALL Java_com_jacob_com_Variant_getVariantType (JNIEnv *, jobject); /* @@ -577,10 +498,10 @@ JNIEXPORT void JNICALL Java_com_jacob_com_Variant_SerializationReadFromBytes /* * Class: com_jacob_com_Variant - * Method: isNull + * Method: isVariantConsideredNull * Signature: ()Z */ -JNIEXPORT jboolean JNICALL Java_com_jacob_com_Variant_isNull +JNIEXPORT jboolean JNICALL Java_com_jacob_com_Variant_isVariantConsideredNull (JNIEnv *, jobject); /* diff --git a/samples/com/jacob/samples/access/Access.java b/samples/com/jacob/samples/access/Access.java index 25069dc..827fc6f 100644 --- a/samples/com/jacob/samples/access/Access.java +++ b/samples/com/jacob/samples/access/Access.java @@ -23,7 +23,8 @@ import com.jacob.com.*; import com.jacob.activeX.*; /** - * this + * May need to run with some command line options. If so, then try these + * -Djava.library.path=d:/jacob/release -Dcom.jacob.autogc=false -Dcom.jacob.debug=true -Xcheck:jni * @author joe * */ @@ -124,7 +125,7 @@ class Access public static String[] getColumns(Dispatch recset) { Dispatch flds = Dispatch.get(recset, "Fields").toDispatch(); - int n_flds = Dispatch.get(flds, "Count").toInt(); + int n_flds = Dispatch.get(flds, "Count").getInt(); String[] s = new String[n_flds]; Variant vi = new Variant(); for (int i=0;i * This method added 12/2005 for possible use by jacobgen instead of its conversion code - * @return java.util.Date - * (after possible conversion) + *

    + * This does not convert the data + * @deprecated callers should use getDate() + * @return java.util.Date version of this variant if it is a date, otherwise null + * */ public Date toJavaDate(){ - double windowsDate = toDate(); - if (windowsDate == 0){ - return null; - } else { - return DateUtilities.convertWindowsTimeToDate(getDate()); - } + changeType(Variant.VariantDate); + return getJavaDate(); } /** + * @deprecated should be replaced by changeType() followed by getBoolean() * @return the value of this variant as boolean (after possible conversion) */ - public native boolean toBoolean(); + public boolean toBoolean(){ + changeType(Variant.VariantBoolean); + return getBoolean(); + } /** @return the value of this variant as an enumeration (java style) */ public native EnumVariant toEnumVariant(); @@ -173,22 +184,42 @@ public class Variant extends JacobObject { /** * Set this Variant's type to VT_NULL (the VB equivalent of NULL) * */ - public native void putNull(); + private native void putVariantNull(); + /** + * Set this Variant's type to VT_NULL (the VB equivalent of NULL) + * */ + public void putNull(){ + // verify we aren't released yet + getvt(); + putVariantNull(); + } + /** * @deprecated No longer used * @return null ! */ public native Variant cloneIndirect(); - /** @return the content of this variant as a double */ - public native double toDouble(); + /** + * @deprecated should call changeType() then getDouble() + * @return the content of this variant as a double + * (after possible conversion) + **/ + public double toDouble(){ + changeType(Variant.VariantDouble); + return getDouble(); + } /** + * @deprecated should be replaced by changeType() followed by getCurrency * @return the content of this variant as a long reprensenting a monetary * amount */ - public native long toCurrency(); + public long toCurrency(){ + changeType(Variant.VariantCurrency); + return getCurrency(); + } /** * @deprecated superceded by SafeArray @@ -211,6 +242,7 @@ public class Variant extends JacobObject { /** * Exists to support jacobgen. * This would be deprecated if it weren't for jacobgen + * @deprecated superceded by "this" * @return this same object */ public Variant toVariant() { return this; } @@ -228,25 +260,65 @@ public class Variant extends JacobObject { * set the content of this variant to a short (VT_I2|VT_BYREF) * @param in */ - public native void putShortRef(short in); + private native void putVariantShortRef(short in); + + /** + * set the content of this variant to a short (VT_I2|VT_BYREF) + * @param in + */ + public void putShortRef(short in){ + // verify we aren't released + getvt(); + putVariantShortRef(in); + } /** * set the content of this variant to an int (VT_I4|VT_BYREF) * @param in */ - public native void putIntRef(int in); + private native void putVariantIntRef(int in); + + /** + * set the content of this variant to an int (VT_I4|VT_BYREF) + * @param in + */ + public void putIntRef(int in){ + // verify we aren't released + getvt(); + putVariantIntRef(in); + } /** * set the content of this variant to a double (VT_R8|VT_BYREF) * @param in */ - public native void putDoubleRef(double in); + private native void putVariantDoubleRef(double in); + + /** + * set the content of this variant to a double (VT_R8|VT_BYREF) + * @param in + */ + public void putDoubleRef(double in){ + // verify we aren't released + getvt(); + putVariantDoubleRef(in); + } /** * set the content of this variant to a date (VT_DATE|VT_BYREF) * @param in */ - public native void putDateRef(double in); + private native void putVariantDateRef(double in); + + /** + * set the content of this variant to a date (VT_DATE|VT_BYREF) + * @param in + */ + public void putDateRef(double in){ + // verify we aren't released + getvt(); + putVariantDateRef(in); + } /** * converts a java date to a windows time and calls putDateRef(double) @@ -267,43 +339,132 @@ public class Variant extends JacobObject { * set the content of this variant to a string (VT_BSTR|VT_BYREF) * @param in */ - public native void putStringRef(String in); + private native void putVariantStringRef(String in); + /** + * set the content of this variant to a string (VT_BSTR|VT_BYREF) + * @param in + */ + public void putStringRef(String in){ + // verify we aren't released + getvt(); + putVariantStringRef(in); + } /** * get the content of this variant as a short * @return short */ - public native short getShortRef(); + private native short getVariantShortRef(); /** * get the content of this variant as an int * @return int */ - public native int getIntRef(); + public short getShortRef(){ + if ((this.getvt() & VariantShort) == VariantShort && + (this.getvt() & VariantByref) == VariantByref) { + return getVariantShortRef(); + } else { + throw new IllegalStateException( + "getShortRef() only legal on byRef Variants of type VariantShort, not "+this.getvt()); + } + } + + /** + * get the content of this variant as an int + * @return int + */ + private native int getVariantIntRef(); + + /** + * get the content of this variant as an int + * @return int + */ + public int getIntRef(){ + if ((this.getvt() & VariantInt) == VariantInt && + (this.getvt() & VariantByref) == VariantByref) { + return getVariantIntRef(); + } else { + throw new IllegalStateException( + "getIntRef() only legal on byRef Variants of type VariantInt, not "+this.getvt()); + } + } /** * set the content of this variant to a short (VT_I2) * @param in */ - public native void putShort(short in); + private native void putVariantShort(short in); + /** + * set the content of this variant to a short (VT_I2) + * @param in + */ + public void putShort(short in){ + // verify we aren't released + getvt(); + putVariantShort(in); + } /** * get the content of this variant as a short * @return short */ - public native short getShort(); + private native short getVariantShort(); + /** + * return the int value held in this variant (fails on other types?) + * @return int + */ + public short getShort(){ + if (this.getvt() == VariantShort){ + return getVariantShort(); + } else { + throw new IllegalStateException( + "getShort() only legal on Variants of type VariantShort, not "+this.getvt()); + } + } + + /** * get the content of this variant as a double * @return double */ - public native double getDoubleRef(); + private native double getVariantDoubleRef(); + /** + * + * @return returns the double value, throws exception if not a currency type + */ + public double getDobuleRef(){ + if ((this.getvt() & VariantDouble) == VariantDouble && + (this.getvt() & VariantByref) == VariantByref) { + return getVariantDoubleRef(); + } else { + throw new IllegalStateException( + "getDoubleRef() only legal on byRef Variants of type VariantDouble, not "+this.getvt()); + } + } + + /** * get the content of this variant as a double representing a date * @return double */ - public native double getDateRef(); + private native double getVariantDateRef(); + + /** + * + * @return returns the date value as a double, throws exception if not a currency type + */ + public double getDateRef(){ + if ((this.getvt() & VariantDate) == VariantDate && + (this.getvt() & VariantByref) == VariantByref) { + return getVariantDateRef(); + } else { + throw new IllegalStateException( + "getDateRef() only legal on byRef Variants of type VariantDate, not "+this.getvt()); + } + } /** * returns the windows time contained in this Variant to a Java Date @@ -324,7 +485,22 @@ public class Variant extends JacobObject { * get the content of this variant as a string * @return String */ - public native String getStringRef(); + private native String getVariantStringRef(); + + /** + * gets the content of the veriant as a string ref + * @return + */ + public String getStringRef(){ + if ((this.getvt() & VariantString) == VariantString && + (this.getvt() & VariantByref) == VariantByref) { + return getVariantStringRef(); + } else { + throw new IllegalStateException( + "getStringRef() only legal on byRef Variants of type VariantString, not "+this.getvt()); + } + } + /** * @deprecated superceded by SafeArray @@ -341,15 +517,15 @@ public class Variant extends JacobObject { public native void VariantClear(); /** - * @return the content of this variant as a Dispatch object + * @return the content of this variant as a Dispatch object (after possible conversion) */ - public Dispatch toDispatch(){ return toDispatchObject(); } + public Dispatch toDispatch(){ return toVariantDispatch(); } /** * native method used by toDispatch() * @return */ - private native Dispatch toDispatchObject(); + private native Dispatch toVariantDispatch(); /** * this returns null @@ -358,52 +534,133 @@ public class Variant extends JacobObject { public native Object clone(); /** + * This method now correctly implements java toString() semantics * Attempts to return the content of this variant as a string - * Will convert the underlying data type to a string(!) - * @return String + *

      + *
    • "not initialized" if not initialized + *
    • "null" if VariantEmpty, + *
    • "null" if VariantError + *
    • "null" if VariantNull + *
    • the value if we know how to describe one of that type + *
    • "???" if can't convert + * @return String value conversion, */ - public native String toString(); + public String toString(){ + try { + // see if we are in a legal state + getvt(); + } catch (IllegalStateException ise){ + return ""; + } + if (getvt() == VariantEmpty || getvt() == VariantError || getvt() == VariantNull){ + return "null"; + } + if (getvt() == VariantString){ + return getString(); + } + try { + Object foo = toJavaObject(); + // rely on java objects to do the right thing + return foo.toString(); + } catch (NotImplementedException nie){ + // some types do not generate a good description yet + return "Description not available for type: "+getvt(); + } + } /** * return the int value held in this variant (fails on other types?) * @return int */ - public native int getInt(); + private native int getVariantInt(); /** - * return the date (as a double) value held in this variant (fails on other - * types?) - * @return double + * return the int value held in this variant if it is an int or a short. + * Throws for other types. + * @return int contents of the windows membory */ - public native double getDate(); + public int getInt(){ + if (this.getvt() == VariantInt){ + return getVariantInt(); + } else if (this.getvt() == VariantShort){ + return (int)getVariantShort(); + } else { + throw new IllegalStateException( + "getInt() only legal on Variants of type VariantInt, not "+this.getvt()); + } + } /** - * returns the windows time contained in this Variant to a Java Date + * @return double return the date (as a double) value held in this variant (fails on other types?) + */ + private native double getVariantDate(); + + /** + * @return double return the date (as a double) value held in this variant (fails on other types?) + */ + public double getDate(){ + if (this.getvt() == VariantDate){ + return getVariantDate(); + } else { + throw new IllegalStateException( + "getDate() only legal on Variants of type VariantDate, not "+this.getvt()); + } + } + + + /** + * returns the windows time contained in this Variant to a Java Date. * should return null if this is not a date Variant * SF 959382 - * @return java.util.Date + * @return java.util.Date returns the date if this is a VariantDate != 0, + * null if it is a VariantDate == 0 and throws an IllegalStateException if this isn't + * a date. */ public Date getJavaDate(){ - double windowsDate = getDate(); - if (windowsDate == 0){ - return null; + Date returnDate = null; + if (getvt() == VariantDate){ + double windowsDate = getDate(); + if (windowsDate != 0){ + returnDate = DateUtilities.convertWindowsTimeToDate(getDate()); + } } else { - return DateUtilities.convertWindowsTimeToDate(getDate()); + throw new IllegalStateException( + "getJavaDate() only legal on Variants of type VariantDate, not "+this.getvt()); } + return returnDate; } /** - * set the value of this variant + * set the value of this variant and set the type * @param in */ - public native void putInt(int in); + private native void putVariantInt(int in); + + /** + * set the value of this variant and set the type + * @param in + */ + public void putInt(int in){ + // verify we aren't released yet + getvt(); + putVariantInt(in); + } /** * set the value of this variant * @param in */ - public native void putDate(double in); + private native void putVariantDate(double in); + /** + * puts a windows date double into the variant and sets the type + * @param in + */ + public void putDate(double in){ + // verify we aren't released yet + getvt(); + putVariantDate(in); + } /** * converts a java date to a windows time and calls putDate(double) * SF 959382 @@ -422,14 +679,18 @@ public class Variant extends JacobObject { /** * attempts to return the content of this variant as a double * (after possible conversion) + * @deprecated should be replaced by changeType() followed by getByte() * @return byte */ - public native byte toByte(); + public byte toByte(){ + changeType(Variant.VariantByte); + return getByte(); + } /** * same as {@link #toDispatch()} * This is different than the other get methods. - * It calls toDispatch wich will do type conversion. + * It calls toDispatch which will do type conversion. * Most getXXX() methods will return null if the data is not of * the requested type * @return this object as a dispatch (Why isn't this typed as type Dispatch?) @@ -446,31 +707,89 @@ public class Variant extends JacobObject { * @param in */ public void putDispatch(Dispatch in) { - putDispatchObject(in); + putVariantDispatch(in); } /** * * @return the value in this Variant as a boolean, null if not a boolean */ - public native boolean getBoolean(); + private native boolean getVariantBoolean(); + + /** + * + * @return returns the value as a boolean, throws an exception if its not. + */ + public boolean getBoolean(){ + if (this.getvt() == VariantBoolean){ + return getVariantBoolean(); + } else { + throw new IllegalStateException ( + "getBoolean() only legal on Variants of type VariantBoolean, not "+this.getvt()); + } + } /** * * @return the value in this Variant as a byte, null if not a byte */ - public native byte getByte(); + private native byte getVariantByte(); - public native void putBoolean(boolean in); + /** + * + * @return returns the value as a boolean, throws an exception if its not. + */ + public byte getByte(){ + if (this.getvt() == VariantByte){ + return getVariantByte(); + } else { + throw new IllegalStateException( + "getByte() only legal on Variants of type VariantByte, not "+this.getvt()); + } + } - public native void putByte(byte in); + /** + * puts a boolean into the variant and sets it's type + * @param in the new value + */ + private native void putVariantBoolean(boolean in); + + /** + * puts a boolean into the variant and sets it's type + * @param in the new value + */ + public void putBoolean(boolean in){ + // verify we aren't released yet + getvt(); + putVariantBoolean(in); + } - public native int toError(); + private native void putVariantByte(byte in); + + /** + * pushes a byte into the varaint and sets the type + * @param in + */ + public void putByte(byte in){ + // verify we aren't released yet + getvt(); + putVariantByte(in); + } + + /** + * converts to an error type and returns the error + * @deprecated should use changeType() followed by getError() + * @return the error as an int (after conversion) + */ + public int toError(){ + changeType(Variant.VariantError); + return getError(); + } /** * Acts a a cover for toDispatch. * This primarily exists to support jacobgen. - * This should be deprecated. + * @deprecated this is a cover for toDispatch(); * @return Object returned by toDispatch() * @see Variant#toDispatch() instead */ @@ -489,110 +808,405 @@ public class Variant extends JacobObject { /** * Sets the type to VariantEmpty. No values needed */ - public native void putEmpty(); + private native void putVariantEmpty(); /** - * Sets the type to VariantDispatch and sets teh value to null + * sets the type to VariantEmpty + * + */ + public void putEmpty(){ + // verify we aren't released yet + getvt(); + putVariantEmpty(); + } + + /** + * Sets the type to VariantDispatch and sets the value to null * Equivalent to VB's nothing */ - public native void putNothing(); + private native void putVariantNothing(); + + /** + * Sets the type to VariantDispatch and sets the value to null + * Equivalent to VB's nothing + */ + public void putNothing(){ + // verify we aren't released yet + getvt(); + putVariantNothing(); + } - public native int getError(); + private native int getVariantError(); - public native void putError(int in); + /** + * @return double return the error value held in this variant (fails on other types?) + */ + public int getError(){ + if (this.getvt() == VariantError){ + return getVariantError(); + } else { + throw new IllegalStateException( + "getError() only legal on Variants of type VariantError, not "+this.getvt()); + } + } - public native double getDouble(); + + private native void putVariantError(int in); + + /** + * puts an error code (?) into the variant and sets the type + * @param in + */ + public void putError(int in){ + // verify we aren't released yet + getvt(); + putVariantError(in); + } - public native void putCurrency(long in); + private native double getVariantDouble(); + + /** + * @return double return the double value held in this variant (fails on other types?) + */ + public double getDouble(){ + if (this.getvt() == VariantDouble){ + return getVariantDouble(); + } else { + throw new IllegalStateException( + "getDouble() only legal on Variants of type VariantDouble, not "+this.getvt()); + } + } + + + private native void putVariantCurrency(long in); + + /** + * puts a value in as a currency and sets the variant type + * @param in + */ + public void putCurrency(long in){ + // verify we aren't released yet + getvt(); + putVariantCurrency(in); + } /** * Puts an object into the Variant -- converts to Dispatch. - * Acts as a cover for putDispatchObject(); + * Acts as a cover for putVariantDispatch(); * This primarily exists to support jacobgen. * This should be deprecated. - * @see Variant#putDispatch(Dispatch) + * @see Variant#putDispatch(Dispatch) + * @deprecated should use putDispatch() * */ public void putObject(Object in){ // this should verify in instanceof Dispatch - putDispatchObject(in); } + putVariantDispatch(in); } /** - * a cover for putDispatch() but is named differently so that + * the JNI implementation for putDispatch() so that * we can screen the incoming dispatches in putDispatch() before this * is invoked - * @param in + * @param in should be a dispatch object */ - private native void putDispatchObject(Object in); + private native void putVariantDispatch(Object in); - public native void putDouble(double in); + private native void putVariantDouble(double in); + + public void putDouble(double in){ + // verify we aren't released yet + getvt(); + putVariantDouble(in); + } /** * * @return the value in this Variant as a long, null if not a long */ - public native long getCurrency(); + private native long getVariantCurrency(); + + /** + * + * @return returns the currency value as a long, throws exception if not a currency type + */ + public long getCurrency(){ + if (this.getvt() == VariantCurrency){ + return getVariantCurrency(); + } else { + throw new IllegalStateException( + "getCurrency() only legal on Variants of type VariantCurrency, not "+this.getvt()); + } + } - public native void putFloatRef(float in); + private native void putVariantFloatRef(float in); + + /** + * pushes a float into the variant and sets the type + * @param in + */ + public void putFloatRef(float in){ + // verify we aren't released yet + getvt(); + putVariantFloatRef(in); + } - public native void putCurrencyRef(long in); + private native void putVariantCurrencyRef(long in); + + /** + * pushes a long into the variant as currency and sets the type + * @param in + */ + public void putCurrencyRef(long in){ + // verify we aren't released yet + getvt(); + putVariantCurrencyRef(in); + } - public native void putErrorRef(int in); + private native void putVariantErrorRef(int in); + + /** + * pushes an error code into the variant by ref and sets the type + * @param in + */ + public void putErrorRef(int in){ + // verify we aren't released yet + getvt(); + putVariantErrorRef(in); + } - public native void putBooleanRef(boolean in); + private native void putVariantBooleanRef(boolean in); + /** + * pushes a boolean into the variant by ref and sets the type of the variant to boolean + * @param in + */ + public void putBooleanRef(boolean in){ + // verify we aren't released yet + getvt(); + putVariantBooleanRef(in); + } + /** * Just a cover for putObject(). * We shouldn't accept any old random object. * This has been left in to support jacobgen. * This should be deprecated. * @param in + * @deprecated */ public void putObjectRef(Object in) { putObject(in); } - public native void putByteRef(byte in); + private native void putVariantByteRef(byte in); - public native String getString(); + /** + * pushes a byte into the variant by ref and sets the type + * @param in + */ + public void putByteRef(byte in){ + // verify we aren't released yet + getvt(); + putVariantByteRef(in); + } + /** + * Native method that actually extracts a string value from the variant + * @return + */ + private native String getVariantString(); + + /** + * + * @return string contents of the variant. + * @throws IllegalStateException if this variant is not of type String + */ + public String getString(){ + if (getvt() == Variant.VariantString){ + return getVariantString(); + } else { + throw new IllegalStateException( + "getString() only legal on Variants of type VariantString, not "+this.getvt()); + } + } - public native void putString(String in); + private native void putVariantString(String in); - public native float getFloatRef(); + /** + * put a string into the variant and set its type + * @param in + */ + public void putString(String in){ + // verify we aren't released yet + getvt(); + putVariantString(in); + } + + private native float getVariantFloatRef(); - public native long getCurrencyRef(); + /** + * + * @return returns the float value, throws exception if not a currency type + */ + public float getFloatRef(){ + if ((this.getvt() & VariantFloat) == VariantFloat && + (this.getvt() & VariantByref) == VariantByref) { + return getVariantFloatRef(); + } else { + throw new IllegalStateException( + "getFloatRef() only legal on byRef Variants of type VariantFloat, not "+this.getvt()); + } + } - public native int getErrorRef(); - public native boolean getBooleanRef(); + private native long getVariantCurrencyRef(); - public native byte getByteRef(); + /** + * + * @return returns the currency value as a long, throws exception if not a currency type + */ + public long getCurrencyRef(){ + if ((this.getvt() & VariantCurrency) == VariantCurrency && + (this.getvt() & VariantByref) == VariantByref) { + return getVariantCurrencyRef(); + } else { + throw new IllegalStateException( + "getCurrencyRef() only legal on byRef Variants of type VariantCurrency, not "+this.getvt()); + } + } + + private native int getVariantErrorRef(); + + /** + * + * @return returns the error value as an int, throws exception if not a currency type + */ + public int getErrorRef(){ + if ((this.getvt() & VariantError) == VariantError && + (this.getvt() & VariantByref) == VariantByref) { + return getVariantErrorRef(); + } else { + throw new IllegalStateException( + "getErrorRef() only legal on byRef Variants of type VariantError, not "+this.getvt()); + } + } + + + private native boolean getVariantBooleanRef(); + + /** + * public cover for native method + * @return the boolean from a booleanRef + */ + public boolean getBooleanRef(){ + if ((this.getvt() & VariantBoolean) == VariantBoolean && + (this.getvt() & VariantByref) == VariantByref) { + return getVariantBooleanRef(); + } else { + throw new IllegalStateException( + "getBooleanRef() only legal on byRef Variants of type VariantBoolean, not "+this.getvt()); + } + } + + private native byte getVariantByteRef(); + + /** + * public cover for native method + * @return the byte from a booleanRef + */ + public byte getByteRef(){ + if ((this.getvt() & VariantByte) == VariantByte && + (this.getvt() & VariantByref) == VariantByref) { + return getVariantByteRef(); + } else { + throw new IllegalStateException( + "getByteRef() only legal on byRef Variants of type VariantByte, not "+this.getvt()); + } + } + + /** * attempts to return the contents of this variant as a float * (after possible conversion) + * @deprecated should use changeType() and getFloat() instead * @return float */ - public native float toFloat(); + public float toFloat(){ + changeType(Variant.VariantFloat); + return getFloat(); + } + + private native SafeArray toVariantSafeArray(boolean deepCopy); /** * By default toSafeArray makes a deep copy due to the fact that this * Variant owns the embedded SafeArray and will destroy it when it gc's + *

      + * calls toSafeArray(true) */ public SafeArray toSafeArray() { + // verify we haven't been released yet + getvt(); return toSafeArray(true); } + + /** + * This lets folk turn into a safe array without a deep copy. + * Shoudl this API be public? + * @param deepCopy + * @return + */ + public SafeArray toSafeArray(boolean deepCopy){ + // verify we haven't been released yet + getvt(); + return toVariantSafeArray(deepCopy); + } - public native SafeArray toSafeArray(boolean deepCopy); + private native void putVariantSafeArrayRef(SafeArray in); - public native void putSafeArrayRef(SafeArray in); + /** + * have no idea... + * @param in + */ + public void putSafeArrayRef(SafeArray in){ + // verify we haven't been released yet + getvt(); + putVariantSafeArrayRef(in); + } + + private native void putVariantSafeArray(SafeArray in); - public native void putSafeArray(SafeArray in); + /** + * have no idea... + * @param in + */ + public void putSafeArray(SafeArray in){ + // verify we haven't been released yet + getvt(); + putVariantSafeArray(in); + } + /** * sets the type to VT_ERROR and the error message to DISP_E_PARAMNOTFOIUND * */ - public native void noParam(); + private native void putVariantNoParam(); + + /** + * sets the type to VT_ERROR and the error message to DISP_E_PARAMNOTFOIUND + * */ + public void putNoParam(){ + // verify we aren't released yet + getvt(); + putVariantNoParam(); + } + /** + * sets the type to VT_ERROR and the error message to DISP_E_PARAMNOTFOIUND + * @deprecated replaced by putNoParam() + * */ + public void noParam(){ + putNoParam(); + } /** * @deprecated superceded by SafeArray * @throws com.jacob.com.NotImplementedException @@ -605,32 +1219,61 @@ public class Variant extends JacobObject { * * @return returns the value as a float if the type is of type float */ - public native float getFloat(); + private native float getVariantFloat(); + + /** + * @return returns the value as a float if the type is of type float + */ + public float getFloat(){ + if (this.getvt() == VariantFloat){ + return getVariantFloat(); + } else { + throw new IllegalStateException( + "getFloat() only legal on Variants of type VariantFloat, not "+this.getvt()); + } + } + + + /** + * fills the Variant with a float and sets the type to float + * @param in + */ + private native void putVariantFloat(float in); /** * fills the Variant with a float and sets the type to float * @param in */ - public native void putFloat(float in); - + public void putFloat(float in){ + // verify we haven't been released yet + getvt(); + putVariantFloat(in); + } + /** * Dispatch and dispatchRef are treated the same - * This is a cover for putDispatch(). + * This is a cover for putVariantDispatch(). * Dispatch and dispatchRef are treated the same * @param in */ public void putDispatchRef(Dispatch in) { - putDispatchObject(in); + putVariantDispatch(in); } /** * Dispatch and dispatchRef are treated the same - * This is just a cover for getDispatch() + * This is just a cover for getDispatch() with a flag check * @return the results of getDispatch() */ public Dispatch getDispatchRef() { - return getDispatch(); - } + if ((this.getvt() & VariantDispatch) == VariantDispatch && + (this.getvt() & VariantByref) == VariantByref) { + return getDispatch(); + } else { + throw new IllegalStateException( + "getDispatchRef() only legal on byRef Variants of type VariantDispatch, not "+this.getvt()); + } + } /** * @deprecated superceded by SafeArray @@ -649,18 +1292,21 @@ public class Variant extends JacobObject { } /** - * Convertes variant to the passed in type by converting the underlying - * windows variant structure + * Converts variant to the passed in type by converting the underlying + * windows variant structure. private so folks use public java method * @param in the desired resulting type */ - public native void changeType(short in); + private native void changeVariantType(short in); /** - * cover for changeType(short) + * cover for native method so we can cover it. * @param in type to convert this variant too + * @return Variant returns this same object so folks can change when replacing calls + * toXXX() with changeType().getXXX() */ - public void changeType(int in) { - changeType((short) in); + public Variant changeType(short in) { + changeVariantType((short) in); + return this; } /** @@ -673,7 +1319,7 @@ public class Variant extends JacobObject { } /** - * public constructor + * public constructor, initializes and sets type to VariantEmpty */ public Variant() { init(); @@ -790,15 +1436,35 @@ public class Variant extends JacobObject { } } + /** + * Returns the variant type via a native method call + * @return short one of the VT_xx types + */ + private native short getVariantType(); - public native short getvt(); - + /** + * Reports the type of the underlying Variant object + * @return returns the variant type as a short, one of the Variantxxx + * values defined as statics in this class. returns VariantNull if not initialized + */ + public short getvt(){ + if (m_pVariant != 0){ + return getVariantType(); + } else { + throw new IllegalStateException("uninitialized Variant"); + } + } + /** * attempts to return the contents of this Variant as a short * (after possible conversion) + * @deprecated callers should use changeType() followed by getShort() * @return short */ - public native short toShort(); + public short toShort() { + this.changeType(Variant.VariantShort); + return getShort(); + } /** * now private so only this object can asccess was: call this to explicitly @@ -943,30 +1609,44 @@ public class Variant extends JacobObject { * is the variant null or empty or error or null dispatch * @return true if it is null or false if not */ - public native boolean isNull(); + private native boolean isVariantConsideredNull(); + + /** + * + * @return returns true if the variant is considered null + * @throws IllegalStateException if there is no underlying windows memory + */ + public boolean isNull(){ + getvt(); + return isVariantConsideredNull(); + } /** * this is supposed to create a byte array that represents the underlying * variant object struct */ - public native byte[] SerializationWriteToBytes(); + protected native byte[] SerializationWriteToBytes(); /** * this is supposed to cause the underlying variant object struct to * be rebuilt from a previously serialized byte array. * @param ba */ - public native void SerializationReadFromBytes(byte[] ba); + protected native void SerializationReadFromBytes(byte[] ba); /*===================================================================== * * *=====================================================================*/ /** - * Convert a JACOB Variant value to a Java object (type conversions). - * provided in Sourceforge feature request 959381 + * Convert a JACOB Variant value to a Java object + * (type conversions). + * provided in Sourceforge feature request 959381. + * + * Unlike other toXXX() methods, it does not do a type conversion + * except for special data types (it shouldn't do any!) * - * @return Corresponding Java type object. + * @return Corresponding Java object of the type matching the Variant type. * @throws Exception if conversion failed. */ protected Object toJavaObject() throws JacobException { @@ -1010,32 +1690,32 @@ public class Variant extends JacobObject { result = this.getDispatchRef(); break; case Variant.VariantError : //10 - result = new NotImplementedException("Not implemented: VariantError"); + result = new IllegalStateException("toJavaObject() Not implemented for VariantError"); break; case Variant.VariantBoolean : //11 result = new Boolean(this.getBoolean()); break; case Variant.VariantVariant : //12 - result = new NotImplementedException("Not implemented: VariantVariant"); + result = new IllegalStateException("toJavaObject() Not implemented for VariantVariant"); break; case Variant.VariantObject : //13 - result = new NotImplementedException("Not implemented: VariantObject"); + result = new IllegalStateException("toJavaObject() Not implemented for VariantObject"); break; case Variant.VariantByte : //17 result = new Byte(this.getByte()); - //result = new NotImplementedException("Not implemented: VariantByte"); + //result = new IllegalStateException("toJavaObject() Not implemented for VariantByte"); break; case Variant.VariantTypeMask : //4095 - result = new NotImplementedException("Not implemented: VariantTypeMask"); + result = new IllegalStateException("toJavaObject() Not implemented for VariantTypeMask"); break; case Variant.VariantArray : //8192 - result = new NotImplementedException("Not implemented: VariantArray"); + result = new IllegalStateException("toJavaObject() Not implemented for VariantArray"); break; case Variant.VariantByref : //16384 - result = new NotImplementedException("Not implemented: VariantByref"); + result = new IllegalStateException("toJavaObject() Not implemented for VariantByref"); break; default : - result = new NotImplementedException("Unknown return type: " + type); + result = new IllegalStateException("Unknown return type: " + type); result = this; break; }//switch (type) diff --git a/unittest/com/jacob/com/VariantTest.java b/unittest/com/jacob/com/VariantTest.java index 879cb8a..b0e7c83 100644 --- a/unittest/com/jacob/com/VariantTest.java +++ b/unittest/com/jacob/com/VariantTest.java @@ -1,5 +1,7 @@ package com.jacob.com; +import java.util.Date; + /** * runs through some of the get and set methods on Variant * @@ -9,6 +11,8 @@ class VariantTest { public static void main(String[] args) { System.out.println("Testing Started"); VariantTest testJig = new VariantTest(); + testJig.testUninitializedVariant(); + testJig.testToStringDoesNotConvert(); testJig.testPutsAndGets(); testJig.testSafeReleaseBoolean(); testJig.testSafeReleaseConstant(); @@ -26,40 +30,103 @@ class VariantTest { } - private void testSafeReleaseBoolean(){ - Variant v = new Variant(true); - System.out.println("Newly created Variant ("+ v.getBoolean()+") "+ - "trying to create access violation but it doesn't seem to be easy"); - v.safeRelease(); - if (v.getBoolean() != true){ - System.out.println("Variant value ("+v.getBoolean()+") " - +"has been broken by SafeRelease()"); - } else { - System.out.println("Variant value ("+v.getBoolean()+") " - +"has survived SafeRelease()"); + /** + * make sure variant with no backing store works. + * + */ + private void testUninitializedVariant(){ + Variant v; + // Variants created without parameters are auto set to VariantEmpty + v = new Variant(); + try { + if (v.getvt() == Variant.VariantEmpty){ + // successful + // System.out.println("Variant initialized without parameters correctly set to empty"); + } else { + throw new RuntimeException("getvt() on uninitialized variant shoud have returned VariantEmpty, instead returned "+v.getvt()); + } + } catch (IllegalStateException ise){ + throw new RuntimeException("getvt() on uninitialized variant shoud have succeeded, but instead threw exception"); } + try { + v.toString(); + } catch (IllegalStateException ise){ + System.out.println("toString() should never throw a runtime exception"); + throw new RuntimeException("toString() should not blow up even with uninitialized Variant"); + } + + } + + + /** + * + * verify the toString() method does not do type conversion + */ + private void testToStringDoesNotConvert(){ + Variant v; + v = new Variant(true); + v.toString(); + if (v.getvt() != Variant.VariantBoolean){ + throw new RuntimeException("toString() converted boolean to something else"); + } else { + //System.out.println("toString() correctly does not convert type"); + } + if (v.getBoolean() != true){ + System.out.println("toString() converted boolean true to "+ v.getBoolean()); + } + v = new Variant(false); + v.toString(); + if (v.getvt() != Variant.VariantBoolean){ + throw new RuntimeException("toString() converted boolean to something else"); + } else { + //System.out.println("toString() correctly does not convert type"); + } + if (v.getBoolean() != false){ + System.out.println("toString() converted boolean false to "+ v.getBoolean()); + } + } + + private void testSafeReleaseBoolean(){ + Variant v; + v = new Variant(true); + //System.out.println("Newly created Variant ("+ v.getBoolean()+") "+ + // "trying to create access violation but it doesn't seem to be easy"); + v.safeRelease(); + try { + v.getBoolean(); + System.out.println("IllegalStateException should have been thrown when querying safeReleased object"); + throw new RuntimeException("test failed"); + } catch (IllegalStateException ise){ + //System.out.println("IllegalStateException correctly thrown after safeRelease"); + } + v = new Variant(true); for ( int i = 0 ; i < 10; i ++){ new Variant ("xxx"+i); new Variant(i); new Variant ("yyy"+i); } ComThread.Release(); - if (v.getBoolean() != true){ - System.out.println("Variant value ("+v.getBoolean()+") " - +"has been broken by ComThread.Release()"); - } else { - System.out.println("Variant value ("+v.getBoolean()+") " - +"has been survived by ComThread.Release()"); + try { + v.getBoolean(); + System.out.println("IllegalStateException should have been thrown when querying ComThread.Release"); + throw new RuntimeException("test failed"); + } catch (IllegalStateException ise){ + //System.out.println("IllegalStateException correctly thrown after ComThread.Release"); } } + /** + * verify the constant values aren't released with safeRelease + * + */ private void testSafeReleaseConstant(){ System.out.println("Using Static constant Variant - should never throw access violation"); Variant.VT_TRUE.safeRelease(); if (Variant.VT_TRUE.getBoolean() != true){ System.out.println("VT_TRUE has been broken by SafeRelease()"); + throw new RuntimeException("test failed"); } else { - System.out.println("VT_TRUE survived SafeRelease()"); + //System.out.println("VT_TRUE survived SafeRelease()"); } for ( int i = 0 ; i < 10; i ++){ @@ -71,24 +138,31 @@ class VariantTest { if (Variant.VT_TRUE.getBoolean() != true){ System.out.println("VT_TRUE has been broken by ComThread.Release()"); + throw new RuntimeException("test failed"); } else { - System.out.println("VT_TRUE survived ComThread.Release()"); + //System.out.println("VT_TRUE survived ComThread.Release()"); } } + /** + * this used to try and and create an access violation but that + * didn't work and now the methods on the Variant are smarter about + * working after a release + * + */ private void testSafeReleaseString(){ String mTestString = "Guitar Hero"; Variant v = new Variant(mTestString); - System.out.println("Newly created Variant ("+ v.getString()+") "+ - "trying to create access violation but it doesn't seem to be easy"); + //System.out.println("Newly created Variant ("+ v.getString()+") "+ + // "about to safe release and then access"); v.safeRelease(); - if (v.getString() == null || !v.getString().equals(mTestString)){ - System.out.println("Variant value ("+v.getString()+") " - +"has been broken by SafeRelease()"); - } else { - System.out.println("Variant value ("+v.getString()+") " - +"has survived SafeRelease()"); + try { + v.getString(); + System.out.println("IllegalStateException should have been thrown when querying safeReleased object"); + throw new RuntimeException("test failed"); + } catch (IllegalStateException ise){ + //System.out.println("IllegalStateException correctly thrown after safeRelease"); } } @@ -127,28 +201,47 @@ class VariantTest { private void testPutsAndGets(){ Variant v = new Variant(); v.putInt(10); - if (v.toInt() != 10){ + if (v.getInt() != 10){ System.out.println("int test failed"); } - v.putInt(10); - if (v.toDouble() != 10.0){ + v.putShort((short)10); + if (v.getShort() != 10){ + System.out.println("short test failed"); + } + v.putByte((byte)10); + if (v.getByte() != 10){ + System.out.println("int test failed"); + } + v.putFloat(10); + if (v.getFloat() != 10.0){ + System.out.println("float test failed"); + } + v.putDouble(10); + if (v.getDouble() != 10.0){ System.out.println("double test failed"); } v.putString("1234.567"); - if (!"1234.567".equals(v.toString())){ + if (!"1234.567".equals(v.getString())){ System.out.println("string test failed"); } v.putBoolean(true); - if (v.toBoolean() != true){ + if (v.getBoolean() != true){ System.out.println("failed boolean test(true)"); } v.putBoolean(false); - if (v.toBoolean() != false){ + if (v.getBoolean() != false){ System.out.println("failed boolean test(false)"); } v.putCurrency(123456789123456789L); - if (v.toCurrency()!=123456789123456789L){ - System.out.println("failed long test"); + if (v.getCurrency()!=123456789123456789L){ + System.out.println("failed currency test"); + } + + Date ourDate = new Date(); + v.putDate(ourDate); + Date retrievedDate = v.getJavaDate(); + if (!retrievedDate.equals(ourDate)){ + System.out.println("failed java date load and unload"); } v.putNull(); diff --git a/unittest/com/jacob/test/events/IETest.java b/unittest/com/jacob/test/events/IETest.java index 056fd74..46cd0bd 100644 --- a/unittest/com/jacob/test/events/IETest.java +++ b/unittest/com/jacob/test/events/IETest.java @@ -34,10 +34,12 @@ class IETest //e.printStackTrace(); } } - System.out.println("Thread quit, about to quit main sta"); + System.out.println("Main: Thread quit, about to quit main sta in thread " + +Thread.currentThread().getName()); // this line only does someting if startMainSTA() was called ComThread.quitMainSTA(); - System.out.println("did quit main sta"); + System.out.println("Main: did quit main sta in thread " + +Thread.currentThread().getName()); } } @@ -59,22 +61,33 @@ class IETestThread extends Thread try { Dispatch.put(ie, "Visible", new Variant(true)); Dispatch.put(ie, "AddressBar", new Variant(true)); - System.out.println(Dispatch.get(ie, "Path")); + System.out.println("IETestThread: " + Dispatch.get(ie, "Path")); Dispatch.put(ie, "StatusText", new Variant("My Status Text")); + System.out.println("IETestThread: About to hookup event listener"); IEEvents ieE = new IEEvents(); new DispatchEvents((Dispatch) ie, ieE,"InternetExplorer.Application.1"); + System.out.println("IETestThread: Did hookup event listener"); + /// why is this here? Was there some other code here in the past? Variant optional = new Variant(); - optional.noParam(); + optional.putNoParam(); + System.out.println("IETestThread: About to call navigate to sourceforge"); Dispatch.call(ie, "Navigate", new Variant("http://sourceforge.net/projects/jacob-project")); + System.out.println("IETestThread: Did call navigate to sourceforge"); try { Thread.sleep(delay); } catch (Exception e) {} + System.out.println("IETestThread: About to call navigate to yahoo"); Dispatch.call(ie, "Navigate", new Variant("http://groups.yahoo.com/group/jacob-project")); + System.out.println("IETestThread: Did call navigate to yahoo"); try { Thread.sleep(delay); } catch (Exception e) {} } catch (Exception e) { e.printStackTrace(); + } catch (Throwable re){ + re.printStackTrace(); } finally { - ie.invoke("Quit", new Variant[] {}); + System.out.println("IETestThread: About to send Quit"); + ie.invoke("Quit", new Variant[] {}); + System.out.println("IETestThread: Did send Quit"); } // this blows up when it tries to release a DispatchEvents object // I think this is because there is still one event we should get back @@ -83,13 +96,14 @@ class IETestThread extends Thread // freed before the callback // commenting out ie.invoke(quit...) causes this to work without error // this code tries to wait until the quit has been handled but that doesn't work - System.out.println("IETest: Waiting until we've received the quit callback"); + System.out.println("IETestThread: Waiting until we've received the quit callback"); while (!quitHandled){ try { Thread.sleep(delay/5);} catch (InterruptedException e) {} } + System.out.println("IETestThread: Received the quit callback"); // wait a little while for it to end - try {Thread.sleep(delay); } catch (InterruptedException e) {} - System.out.println("IETest: about to call release in thread " + + //try {Thread.sleep(delay); } catch (InterruptedException e) {} + System.out.println("IETestThread: about to call ComThread.Release in thread " + Thread.currentThread().getName()); ComThread.Release(); @@ -101,76 +115,76 @@ class IETestThread extends Thread public class IEEvents { public void BeforeNavigate2(Variant[] args) { - System.out.println("IEEvents: BeforeNavigate2"); + System.out.println("IEEvents Received ("+Thread.currentThread().getName()+"): BeforeNavigate2 "+args.length); } public void CommandStateChange(Variant[] args) { - System.out.println("IEEvents: CommandStateChange"); + System.out.println("IEEvents Received ("+Thread.currentThread().getName()+"): CommandStateChange "+args.length); } public void DocumentComplete(Variant[] args) { - System.out.println("IEEvents: DocumentComplete"); + System.out.println("IEEvents Received ("+Thread.currentThread().getName()+"): DocumentComplete "+args.length); } public void DownloadBegin(Variant[] args) { - System.out.println("IEEvents: DownloadBegin"); + System.out.println("IEEvents Received ("+Thread.currentThread().getName()+"): DownloadBegin "+args.length); } public void DownloadComplete(Variant[] args) { - System.out.println("IEEvents: DownloadComplete"); + System.out.println("IEEvents Received ("+Thread.currentThread().getName()+"): DownloadComplete "+args.length); } public void NavigateComplete2(Variant[] args) { - System.out.println("IEEvents: NavigateComplete2"); + System.out.println("IEEvents Received ("+Thread.currentThread().getName()+"): NavigateComplete "+args.length); } public void NewWindow2(Variant[] args) { - System.out.println("IEEvents: NewWindow2"); + System.out.println("IEEvents Received ("+Thread.currentThread().getName()+"): NewWindow2 "+args.length); } public void OnFullScreen(Variant[] args) { - System.out.println("IEEvents: OnFullScreen"); + System.out.println("IEEvents Received ("+Thread.currentThread().getName()+"): OnFullScreen "+args.length); } public void OnMenuBar(Variant[] args) { - System.out.println("IEEvents: OnMenuBar"); + System.out.println("IEEvents Received ("+Thread.currentThread().getName()+"): OnMenuBar "+args.length); } public void OnQuit(Variant[] args) { - System.out.println("IEEvents: OnQuit"); + System.out.println("IEEvents Received ("+Thread.currentThread().getName()+"): OnQuit "+args.length); IETestThread.quitHandled = true; } public void OnStatusBar(Variant[] args) { - System.out.println("IEEvents: OnStatusBar"); + System.out.println("IEEvents Received ("+Thread.currentThread().getName()+"): OnStatusBar "+args.length); } public void OnTheaterMode(Variant[] args) { - System.out.println("IEEvents: OnTheaterMode"); + System.out.println("IEEvents Received ("+Thread.currentThread().getName()+"): OnTheaterMode "+args.length); } public void OnToolBar(Variant[] args) { - System.out.println("IEEvents: OnToolBar"); + System.out.println("IEEvents Received ("+Thread.currentThread().getName()+"): OnToolBar "+args.length); } public void OnVisible(Variant[] args) { - System.out.println("IEEvents: OnVisible"); + System.out.println("IEEvents Received ("+Thread.currentThread().getName()+"): OnVisible "+args.length); } public void ProgressChange(Variant[] args) { - System.out.println("IEEvents: ProgressChange"); + System.out.println("IEEvents Received ("+Thread.currentThread().getName()+"): ProgressChange "+args.length); } public void PropertyChange(Variant[] args) { - System.out.println("IEEvents: PropertyChange"); + System.out.println("IEEvents Received ("+Thread.currentThread().getName()+"): PropertyChange "+args.length); } public void StatusTextChange(Variant[] args) { - System.out.println("IEEvents: StatusTextChange"); + System.out.println("IEEvents Received ("+Thread.currentThread().getName()+"): StatusTextChange "+args.length); } public void TitleChange(Variant[] args) { - System.out.println("IEEvents: TitleChange"); + System.out.println("IEEvents Received ("+Thread.currentThread().getName()+"): TitleChange "+args.length); } }