diff --git a/jni/Dispatch.cpp b/jni/Dispatch.cpp index 154fb60..bceee72 100644 --- a/jni/Dispatch.cpp +++ b/jni/Dispatch.cpp @@ -89,7 +89,7 @@ JNIEXPORT jobject JNICALL Java_com_jacob_com_Dispatch_QueryInterface * and connects to it. does special code if the progid * is of the alternate format (with ":") **/ -JNIEXPORT void JNICALL Java_com_jacob_com_Dispatch_createInstance +JNIEXPORT void JNICALL Java_com_jacob_com_Dispatch_createInstanceNative (JNIEnv *env, jobject _this, jstring _progid) { jclass clazz = env->GetObjectClass(_this); @@ -155,7 +155,7 @@ doDisp: * attempts to connect to an running instance of the requested program * This exists solely for the factory method connectToActiveInstance. **/ -JNIEXPORT void JNICALL Java_com_jacob_com_Dispatch_getActiveInstance +JNIEXPORT void JNICALL Java_com_jacob_com_Dispatch_getActiveInstanceNative (JNIEnv *env, jobject _this, jstring _progid) { jclass clazz = env->GetObjectClass(_this); @@ -197,7 +197,7 @@ JNIEXPORT void JNICALL Java_com_jacob_com_Dispatch_getActiveInstance * starts up a new instance of the requested program (progId). * This exists solely for the factory method connectToActiveInstance. **/ -JNIEXPORT void JNICALL Java_com_jacob_com_Dispatch_coCreateInstance +JNIEXPORT void JNICALL Java_com_jacob_com_Dispatch_coCreateInstanceNative (JNIEnv *env, jobject _this, jstring _progid) { jclass clazz = env->GetObjectClass(_this); diff --git a/jni/Dispatch.h b/jni/Dispatch.h index f25a6a0..861f22e 100644 --- a/jni/Dispatch.h +++ b/jni/Dispatch.h @@ -38,7 +38,7 @@ JNIEXPORT jobject JNICALL Java_com_jacob_com_Dispatch_QueryInterface * Method: createInstance * Signature: (Ljava/lang/String;)V */ -JNIEXPORT void JNICALL Java_com_jacob_com_Dispatch_createInstance +JNIEXPORT void JNICALL Java_com_jacob_com_Dispatch_createInstanceNative (JNIEnv *, jobject, jstring); /* @@ -46,7 +46,7 @@ JNIEXPORT void JNICALL Java_com_jacob_com_Dispatch_createInstance * Method: getActiveInstance * Signature: (Ljava/lang/String;)V */ -JNIEXPORT void JNICALL Java_com_jacob_com_Dispatch_getActiveInstance +JNIEXPORT void JNICALL Java_com_jacob_com_Dispatch_getActiveInstanceNative (JNIEnv *, jobject, jstring); /* @@ -54,7 +54,7 @@ JNIEXPORT void JNICALL Java_com_jacob_com_Dispatch_getActiveInstance * Method: coCreateInstance * Signature: (Ljava/lang/String;)V */ -JNIEXPORT void JNICALL Java_com_jacob_com_Dispatch_coCreateInstance +JNIEXPORT void JNICALL Java_com_jacob_com_Dispatch_coCreateInstanceNative (JNIEnv *, jobject, jstring); /* diff --git a/jni/Variant.cpp b/jni/Variant.cpp index 3019157..cd07f50 100644 --- a/jni/Variant.cpp +++ b/jni/Variant.cpp @@ -100,87 +100,60 @@ void zeroVariant(JNIEnv *env, jobject _this) env->SetIntField(_this, jf, (unsigned int)0); } -JNIEXPORT void JNICALL Java_com_jacob_com_Variant_Save - (JNIEnv *env, jobject _this, jobject outStream) -{ + +/** + * This is the core of the old Save method. + * It copies this variant to a byte stream. + * The unmarshalling part of this doesn't work but it was left in + * with the hope that someone will want to fix this later + **/ +JNIEXPORT jbyteArray JNICALL Java_com_jacob_com_Variant_SerializationWriteToBytes + (JNIEnv *env, jobject _this){ VARIANT *v = extractVariant(env, _this); - if (v) - { - DWORD flags = MSHCTX_LOCAL; - jint size = VARIANT_UserSize(&flags, 0L, v); - // allocate a byte array of the right length - jbyte* pBuf = new jbyte[size]; - // clear it out - ZeroMemory(pBuf, size); - // marshall the Variant into the buffer - VARIANT_UserMarshal(&flags, (unsigned char *)pBuf, v); - // need to convert the buffer to a java byte ba[] - jbyteArray ba = env->NewByteArray(size); - env->SetByteArrayRegion(ba, 0, size, pBuf); - // and delete the original memory - delete [] pBuf; - - //java code: DataOutputStream dos = new DataOutputStream(outStream); - jclass dosCls = env->FindClass("java/io/DataOutputStream"); - jmethodID dosCons = - env->GetMethodID(dosCls, "", "(Ljava/io/OutputStream;)V"); - jmethodID dosWriteInt = - env->GetMethodID(dosCls, "writeInt", "(I)V"); - jmethodID dosWriteBytes = - env->GetMethodID(dosCls, "write", "([B)V"); - jobject dos = env->NewObject(dosCls, dosCons, outStream); - // write the size into the stream - env->CallVoidMethod(dos, dosWriteInt, size); - // write the buffer into the stream - env->CallVoidMethod(dos, dosWriteBytes, ba); + if (v) + { + DWORD flags = MSHCTX_LOCAL; + jint size = VARIANT_UserSize(&flags, 0L, v); + // allocate a byte array of the right length + jbyte* pBuf = new jbyte[size]; + // clear it out + ZeroMemory(pBuf, size); + // marshall the Variant into the buffer + VARIANT_UserMarshal(&flags, (unsigned char *)pBuf, v); + // need to convert the buffer to a java byte ba[] + jbyteArray ba = env->NewByteArray(size); + env->SetByteArrayRegion(ba, 0, size, pBuf); + // and delete the original memory + delete [] pBuf; + return ba; + } else { + jbyteArray ba = env->NewByteArray(0); + return ba; + } } -} - -JNIEXPORT void JNICALL Java_com_jacob_com_Variant_Load - (JNIEnv *env, jobject _this, jobject inStream) -{ + +/** + * This is the core of the old Load method. It is broken because the + * unmarshalling code doesn't work under 2000/XP. + * + * It probably needs a custom handler. + **/ +JNIEXPORT void JNICALL Java_com_jacob_com_Variant_SerializationReadFromBytes + (JNIEnv *env, jobject _this, jbyteArray ba){ VARIANT *v = extractVariant(env, _this); - if (!v) - { - // since the default constructor is not called when serializing in - // I need to init the underlying VARIANT - jclass clazz = env->GetObjectClass(_this); - jfieldID jf = env->GetFieldID( clazz, VARIANT_FLD, "I"); - v = new VARIANT(); - VariantInit(v); - env->SetIntField(_this, jf, (unsigned int)v); - } - if (v) - { - //java code: DataInputStream dis = new DataInputStream(outStream); - jclass disCls = env->FindClass("java/io/DataInputStream"); - jmethodID disCons = - env->GetMethodID(disCls, "", "(Ljava/io/InputStream;)V"); - jmethodID disReadInt = - env->GetMethodID(disCls, "readInt", "()I"); - jmethodID disReadBytes = - env->GetMethodID(disCls, "readFully", "([B)V"); - jobject dis = env->NewObject(disCls, disCons, inStream); - - // read in the size from the input stream - jint size = env->CallIntMethod(dis, disReadInt); - // allocate a byte array of this size - jbyteArray ba = env->NewByteArray(size); - // read it in from the input stream - env->CallVoidMethod(dis, disReadBytes, ba); - if ( size > 0 ) - { + if (v){ // get a buffer from it jbyte *pBuf = env->GetByteArrayElements(ba, 0); // unmarshall the Variant from the buffer DWORD flags = MSHCTX_LOCAL; + printf("about to unmarshall array elements\n"); VARIANT_UserUnmarshal(&flags, (unsigned char *)pBuf, v); // release the byte array + printf("about to release array elements\n"); env->ReleaseByteArrayElements(ba, pBuf, 0); } } -} JNIEXPORT jint JNICALL Java_com_jacob_com_Variant_toInt (JNIEnv *env, jobject _this) @@ -947,12 +920,6 @@ JNIEXPORT jboolean JNICALL Java_com_jacob_com_Variant_getBooleanRef return NULL; } -JNIEXPORT jobject JNICALL Java_com_jacob_com_Variant_getObjectRef - (JNIEnv *env, jobject _this) -{ - return NULL; -} - JNIEXPORT jbyte JNICALL Java_com_jacob_com_Variant_getByteRef (JNIEnv *env, jobject _this) diff --git a/jni/Variant.h b/jni/Variant.h index 93d5ee1..37eb5f4 100644 --- a/jni/Variant.h +++ b/jni/Variant.h @@ -489,14 +489,6 @@ JNIEXPORT jint JNICALL Java_com_jacob_com_Variant_getErrorRef JNIEXPORT jboolean JNICALL Java_com_jacob_com_Variant_getBooleanRef (JNIEnv *, jobject); -/* - * Class: com_jacob_com_Variant - * Method: getObjectRef - * Signature: ()Ljava/lang/Object; - */ -JNIEXPORT jobject JNICALL Java_com_jacob_com_Variant_getObjectRef - (JNIEnv *, jobject); - /* * Class: com_jacob_com_Variant * Method: getByteRef @@ -601,22 +593,12 @@ JNIEXPORT void JNICALL Java_com_jacob_com_Variant_release JNIEXPORT void JNICALL Java_com_jacob_com_Variant_init (JNIEnv *, jobject); -/* - * Class: com_jacob_com_Variant - * Method: Save - * Signature: (Ljava/io/OutputStream;)V - */ -JNIEXPORT void JNICALL Java_com_jacob_com_Variant_Save - (JNIEnv *, jobject, jobject); - -/* - * Class: com_jacob_com_Variant - * Method: Load - * Signature: (Ljava/io/InputStream;)V - */ -JNIEXPORT void JNICALL Java_com_jacob_com_Variant_Load - (JNIEnv *, jobject, jobject); +JNIEXPORT jbyteArray JNICALL Java_com_jacob_com_Variant_SerializationWriteToBytes + (JNIEnv *, jobject); +JNIEXPORT void JNICALL Java_com_jacob_com_Variant_SerializationReadFromBytes + (JNIEnv *, jobject, jbyteArray); + /* * Class: com_jacob_com_Variant * Method: isNull diff --git a/samples/com/jacob/samples/applet/AppTest.java b/samples/com/jacob/samples/applet/AppTest.java index 6c81068..c185981 100644 --- a/samples/com/jacob/samples/applet/AppTest.java +++ b/samples/com/jacob/samples/applet/AppTest.java @@ -24,8 +24,6 @@ public class AppTest extends Applet implements ActionListener { ActiveXComponent sC = null; - Dispatch sControl = null; - /** * startup method */ @@ -46,10 +44,9 @@ public class AppTest extends Applet implements ActionListener { if (sC == null) { String lang = "VBScript"; sC = new ActiveXComponent("ScriptControl"); - sControl = sC.getObject(); - Dispatch.put(sControl, "Language", lang); + Dispatch.put(sC, "Language", lang); } - Variant v = Dispatch.call(sControl, "Eval", in.getText()); + Variant v = Dispatch.call(sC, "Eval", in.getText()); out.setText(v.toString()); } } diff --git a/samples/com/jacob/samples/office/WordDocumentProperties.java b/samples/com/jacob/samples/office/WordDocumentProperties.java index 70e32d4..978415e 100644 --- a/samples/com/jacob/samples/office/WordDocumentProperties.java +++ b/samples/com/jacob/samples/office/WordDocumentProperties.java @@ -1,7 +1,7 @@ package com.jacob.samples.office; import com.jacob.activeX.ActiveXComponent; -import com.jacob.com.ComFailException; +import com.jacob.com.ComException; import com.jacob.com.Dispatch; import com.jacob.com.Variant; @@ -99,7 +99,7 @@ public class WordDocumentProperties { try { cusPropName = Dispatch.call((Dispatch) custDocprops, "Item", cusPropName).toString(); - } catch (ComFailException e) { + } catch (ComException e) { // Do nothing cusPropName = null; } @@ -117,7 +117,7 @@ public class WordDocumentProperties { try { builtInPropName = Dispatch.call((Dispatch) builtInDocProps, "Item", builtInPropName).toString(); - } catch (ComFailException e) { + } catch (ComException e) { // Do nothing builtInPropName = null; } diff --git a/samples/com/jacob/samples/test/safearray.java b/samples/com/jacob/samples/test/SafeArrayViaExcel.java similarity index 95% rename from samples/com/jacob/samples/test/safearray.java rename to samples/com/jacob/samples/test/SafeArrayViaExcel.java index 9f69d53..d80922a 100644 --- a/samples/com/jacob/samples/test/safearray.java +++ b/samples/com/jacob/samples/test/SafeArrayViaExcel.java @@ -3,7 +3,7 @@ package com.jacob.samples.test; import com.jacob.com.*; import com.jacob.activeX.*; -public class safearray +public class SafeArrayViaExcel { public static void main(java.lang.String[] args) { @@ -16,7 +16,8 @@ public class safearray SafeArray sAProdText; Dispatch workbooks = xl.getProperty("Workbooks").toDispatch(); System.out.println("have workbooks"); - Dispatch workbook = Dispatch.call(workbooks, "Open", "d:\\jacob_15\\samples\\test\\jacobtest.xls").toDispatch(); + Dispatch workbook = Dispatch.call(workbooks, "Open", "d:\\jacob\\samples\\test\\ExcelSafeArray" + + ".xls").toDispatch(); System.out.println("Opened File - jacobtest.xls\n"); Dispatch sheet = Dispatch.get(workbook,"ActiveSheet").toDispatch(); cell = Dispatch.invoke(sheet,"Range",Dispatch.Get,new Object[] {"A1:D1000"},new int[1]).toDispatch(); diff --git a/samples/com/jacob/samples/test/jacobtest.xls b/samples/com/jacob/samples/test/SafeArrayViaExcel.xls similarity index 99% rename from samples/com/jacob/samples/test/jacobtest.xls rename to samples/com/jacob/samples/test/SafeArrayViaExcel.xls index 26719c5..6359856 100644 Binary files a/samples/com/jacob/samples/test/jacobtest.xls and b/samples/com/jacob/samples/test/SafeArrayViaExcel.xls differ diff --git a/samples/com/jacob/samples/test/test.java b/samples/com/jacob/samples/test/test.java index 823cae0..59c5d65 100644 --- a/samples/com/jacob/samples/test/test.java +++ b/samples/com/jacob/samples/test/test.java @@ -266,7 +266,7 @@ class test printArray(bback); try { - // this should throw ComFailException + // this should throw ComException bba2.fromCharArray(new char[] {'a'}); } catch (Exception e) { e.printStackTrace(); diff --git a/samples/com/jacob/samples/test/varSerTest.java b/samples/com/jacob/samples/test/varSerTest.java deleted file mode 100644 index ebbc3c0..0000000 --- a/samples/com/jacob/samples/test/varSerTest.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.jacob.samples.test; - -import com.jacob.com.*; -import java.io.*; - -class varSerTest -{ - public static void main(String[] args) throws Exception - { - Variant vs1 = new Variant("hi"); - Variant vs2 = new Variant(123.456); - - FileOutputStream fos = new FileOutputStream("foo.foo"); - vs1.Save(fos); - vs2.Save(fos); - fos.close(); - - Variant vl1 = new Variant(); - Variant vl2 = new Variant(); - FileInputStream fis = new FileInputStream("foo.foo"); - vl1.Load(fis); - vl2.Load(fis); - System.out.println(vl1); - System.out.println(vl2); - - // same thing with serialization - - fos = new FileOutputStream("foo.ser"); - ObjectOutputStream oos = new ObjectOutputStream(fos); - oos.writeObject(vs1); - oos.writeObject(vs2); - oos.close(); - fos.close(); - - - fis = new FileInputStream("foo.ser"); - ObjectInputStream ois = new ObjectInputStream(fis); - - Variant vss1, vss2; - - vss1 = (Variant)ois.readObject(); - vss2 = (Variant)ois.readObject(); - ois.close(); - fis.close(); - - System.out.println(vss1); - System.out.println(vss2); - } -} diff --git a/src/com/jacob/activeX/ActiveXComponent.java b/src/com/jacob/activeX/ActiveXComponent.java index e489858..487a265 100644 --- a/src/com/jacob/activeX/ActiveXComponent.java +++ b/src/com/jacob/activeX/ActiveXComponent.java @@ -101,7 +101,7 @@ public class ActiveXComponent extends Dispatch { ActiveXComponent mCreatedDispatch = null; try { mCreatedDispatch = new ActiveXComponent(); - mCreatedDispatch.coCreateInstanceJava(pRequestedProgramId); + mCreatedDispatch.coCreateInstance(pRequestedProgramId); } catch (Exception e){ mCreatedDispatch =null; if (JacobObject.isDebugEnabled()){ @@ -130,7 +130,7 @@ public class ActiveXComponent extends Dispatch { ActiveXComponent mCreatedDispatch = null; try { mCreatedDispatch = new ActiveXComponent(); - mCreatedDispatch.getActiveInstanceJava(pRequestedProgramId); + mCreatedDispatch.getActiveInstance(pRequestedProgramId); } catch (Exception e){ mCreatedDispatch =null; if (JacobObject.isDebugEnabled()){ diff --git a/src/com/jacob/com/ComFailException.java b/src/com/jacob/com/ComFailException.java index 2a1abf1..f19b83b 100644 --- a/src/com/jacob/com/ComFailException.java +++ b/src/com/jacob/com/ComFailException.java @@ -20,7 +20,7 @@ package com.jacob.com; /** - * COM Fail Exception class raise dwhen there is a problem + * COM Fail Exception class raised when there is a problem */ public class ComFailException extends ComException { /** diff --git a/src/com/jacob/com/ComNotImplementedException.java b/src/com/jacob/com/ComNotImplementedException.java new file mode 100644 index 0000000..dda260c --- /dev/null +++ b/src/com/jacob/com/ComNotImplementedException.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 1999-2004 Sourceforge JACOB Project. + * All rights reserved. Originator: Dan Adler (http://danadler.com). + * Get more information about JACOB at http://sourceforge.net/projects/jacob-project + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +package com.jacob.com; + +/** + * Thrown by java APIs that are not implemented either because + * they were never implemented or because they are bieng deprecated + * This is a subclass of ComException so callers can still just catch + * ComException. + */ +public class ComNotImplementedException extends ComException { + + /** + * + */ + private static final long serialVersionUID = -9169900832852356445L; + + /** + * @param description + */ + public ComNotImplementedException(String description) { + super(description); + } + + +} diff --git a/src/com/jacob/com/Dispatch.java b/src/com/jacob/com/Dispatch.java index dadb062..7d7e34b 100644 --- a/src/com/jacob/com/Dispatch.java +++ b/src/com/jacob/com/Dispatch.java @@ -157,7 +157,7 @@ public class Dispatch extends JacobObject public Dispatch(String requestedProgramId) { programId = requestedProgramId; if (programId != null && !"".equals(programId)){ - createInstance(requestedProgramId); + createInstanceNative(requestedProgramId); } else { throw new IllegalArgumentException( "Dispatch(String) does not accept null or an empty string as a parameter"); @@ -176,7 +176,7 @@ public class Dispatch extends JacobObject * * @param progid */ - private native void createInstance(String progid); + private native void createInstanceNative(String progid); /** * native call getActiveInstance only used by the constructor with the same parm @@ -190,15 +190,18 @@ public class Dispatch extends JacobObject * * @param progid */ - private native void getActiveInstance(String progid); + private native void getActiveInstanceNative(String progid); /** * Wrapper around the native method * @param progid */ - protected void getActiveInstanceJava(String progid){ - this.programId = progid; - getActiveInstance(progid); + protected void getActiveInstance(String pProgramIdentifier){ + if (pProgramIdentifier == null || "".equals(pProgramIdentifier)){ + throw new IllegalArgumentException("program id is required"); + } + this.programId = pProgramIdentifier; + getActiveInstanceNative(pProgramIdentifier); } /** @@ -213,15 +216,18 @@ public class Dispatch extends JacobObject * * @param progid */ - private native void coCreateInstance(String progid); + private native void coCreateInstanceNative(String progid); /** * Wrapper around the native method - * @param progid + * @param pProgramIdentifier */ - protected void coCreateInstanceJava(String progid){ - this.programId = progid; - coCreateInstance(progid); + protected void coCreateInstance(String pProgramIdentifier){ + if (pProgramIdentifier == null || "".equals(pProgramIdentifier)){ + throw new IllegalArgumentException("program id is required"); + } + this.programId = pProgramIdentifier; + coCreateInstanceNative(pProgramIdentifier); } /** @@ -391,11 +397,10 @@ public class Dispatch extends JacobObject * @param dispatchTarget * @param name * @param val - * @throws ClassCastException - * because??? + * @throws com.jacob.com.ComNotImplementedException */ public static void put_Casesensitive(Dispatch dispatchTarget, String name, Object val) { - throw new ClassCastException("not implemented yet"); + throw new ComNotImplementedException("not implemented yet"); } /*============================================================ @@ -447,12 +452,12 @@ public class Dispatch extends JacobObject * @param dispatchTarget * @param name * @param values - * @return never returns anything because throws ClassCastException - * because not implemented yet + * @return never returns anything because + * @throws com.jacob.com.ComNotImplementedException */ public static Variant callN_CaseSensitive(Dispatch dispatchTarget, String name, Object[] values) { - throw new ClassCastException("not implemented yet"); + throw new ComNotImplementedException("not implemented yet"); } /** @@ -1273,13 +1278,14 @@ public class Dispatch extends JacobObject } /** - * not implemented , will throw class cast exception + * not implemented yet * @param dispatchTarget * @param name * @return Variant never returned + * @throws com.jacob.com.ComNotImplementedException */ public static Variant get_CaseSensitive(Dispatch dispatchTarget, String name) { - throw new ClassCastException("not implemented yet"); + throw new ComNotImplementedException("not implemented yet"); } } \ No newline at end of file diff --git a/src/com/jacob/com/DispatchEvents.java b/src/com/jacob/com/DispatchEvents.java index d578e9e..d1ce876 100644 --- a/src/com/jacob/com/DispatchEvents.java +++ b/src/com/jacob/com/DispatchEvents.java @@ -132,7 +132,7 @@ public class DispatchEvents extends JacobObject { * @param progId optional program id. most folks don't need this either * @param typeLib optional parameter for those programs that don't register their type libs (like Excel) */ - protected native void init3(Dispatch src, Object sink, String progId, String typeLib); + private native void init3(Dispatch src, Object sink, String progId, String typeLib); /** * now private so only this object can asccess diff --git a/src/com/jacob/com/Variant.java b/src/com/jacob/com/Variant.java index b95b5da..251e541 100644 --- a/src/com/jacob/com/Variant.java +++ b/src/com/jacob/com/Variant.java @@ -24,9 +24,13 @@ import java.util.Date; /** * The multi-format data type used for all call backs and most communications * between Java and COM. It provides a single class that can handle all data - * types + * types. + *

+ * This object no longer implements Serializable because serialization is broken + * (and has been since 2000/xp). The underlying + * marshalling/unmarshalling code is broken in the JNI layer. */ -public class Variant extends JacobObject implements java.io.Serializable { +public class Variant extends JacobObject { /** * Use this constant for optional parameters */ @@ -157,31 +161,29 @@ public class Variant extends JacobObject implements java.io.Serializable { /** * @deprecated superceded by SafeArray - * @param in - * doesn't matter because this method does nothing - * @throws com.jacob.com.ComFailException + * @param in doesn't matter because this method does nothing + * @throws com.jacob.com.ComNotImplementedException */ public void putVariantArray(Variant[] in) { - throw new ComFailException("Not implemented"); + throw new ComNotImplementedException("Not implemented"); } /** * @deprecated superceded by SafeArray - * @return never returns - * @throws com.jacob.com.ComFailException + * @return never returns anything + * @throws com.jacob.com.ComNotImplementedException */ public Variant[] getVariantArray() { - throw new ComFailException("Not implemented"); + throw new ComNotImplementedException("Not implemented"); } /** * @deprecated superceded by SafeArray - * @param in - * doesn't matter because this method does nothing - * @throws com.jacob.com.ComFailException + * @param in doesn't matter because this method does nothing + * @throws com.jacob.com.ComNotImplementedException */ public void putByteArray(Object in) { - throw new ComFailException("Not implemented"); + throw new ComNotImplementedException("Not implemented"); } /** @@ -287,12 +289,12 @@ public class Variant extends JacobObject implements java.io.Serializable { public native String getStringRef(); /** - * @return never returns anything - * @throws com.jacob.com.ComFailException * @deprecated superceded by SafeArray + * @return never returns anything + * @throws com.jacob.com.ComNotImplementedException */ public Object toCharArray() { - throw new ComFailException("Not implemented"); + throw new ComNotImplementedException("Not implemented"); } /** @@ -427,10 +429,6 @@ public class Variant extends JacobObject implements java.io.Serializable { public native double getDouble(); - public Object getObject() { - return toDispatch(); - } - public native void putCurrency(long in); /** puts an object into the */ @@ -470,8 +468,6 @@ public class Variant extends JacobObject implements java.io.Serializable { public native boolean getBooleanRef(); - public native Object getObjectRef(); - public native byte getByteRef(); /** @@ -498,11 +494,11 @@ public class Variant extends JacobObject implements java.io.Serializable { public native void noParam(); /** - * superceded by SafeArray - * @throws com.jacob.com.ComFailException + * @deprecated superceded by SafeArray + * @throws com.jacob.com.ComNotImplementedException */ public void putCharArray(Object in) { - throw new ComFailException("Not implemented"); + throw new ComNotImplementedException("Not implemented"); } public native float getFloat(); @@ -518,19 +514,19 @@ public class Variant extends JacobObject implements java.io.Serializable { } /** - * superceded by SafeArray - * @throws com.jacob.com.ComFailException + * @deprecated superceded by SafeArray + * @throws com.jacob.com.ComNotImplementedException */ public void putVariantArrayRef(Variant[] in) { - throw new ClassCastException("Not implemented"); + throw new ComNotImplementedException("Not implemented"); } /** - * superceded by SafeArray - * @throws com.jacob.com.ComFailException + * @deprecated superceded by SafeArray + * @throws com.jacob.com.ComNotImplementedException */ public Variant[] getVariantArrayRef() { - throw new ClassCastException("Not implemented"); + throw new ComNotImplementedException("Not implemented"); } public native void changeType(short in); @@ -555,7 +551,7 @@ public class Variant extends JacobObject implements java.io.Serializable { } /** - * constructor that calls init() and then putXXX() + * Constructor that accepts a primitive rather than an object * @param in */ public Variant(int in) { @@ -564,7 +560,7 @@ public class Variant extends JacobObject implements java.io.Serializable { } /** - * constructor that calls init() and then putXXX() + * Constructor that accepts a primitive rather than an object * @param in */ public Variant(double in) { @@ -573,7 +569,7 @@ public class Variant extends JacobObject implements java.io.Serializable { } /** - * constructor that calls init() and then putXXX() + * Constructor that accepts a primitive rather than an object * @param in */ public Variant(boolean in) { @@ -581,33 +577,10 @@ public class Variant extends JacobObject implements java.io.Serializable { putBoolean(in); } - /** - * constructor that calls init() and then putXXX() - * @param in - */ - public Variant(String in) { - init(); - putString(in); - } - - /** - * constructor that calls init() and then putSafeArrayXXX() - * @param in - * @param fByRef is this data by reference or not? - */ - public Variant(SafeArray in, boolean fByRef) { - init(); - if (fByRef) { - putSafeArrayRef(in); - } else { - putSafeArray(in); - } - } - /** - * constructor that calls two parameter constructor - * with 1st parameter as object and 2nd parameter as false - * @param in + * Convenience constructor that calls the main one with + * a byRef value of false + * @param in object to be made into variant */ public Variant(Object in) { this(in, false); @@ -661,45 +634,6 @@ public class Variant extends JacobObject implements java.io.Serializable { } } - /** - * wierd constructor that is no longer supported - * @param in - * @param in1 - * @throws com.jacob.com.ComFailException - */ - public Variant(int in, int in1) { - throw new ComFailException("Not implemented"); - } - - /** - * wierd constructor that is no longer supported - * @param in - * @param in1 - * @throws com.jacob.com.ComFailException - */ - public Variant(int in, boolean in1) { - throw new ComFailException("Not implemented"); - } - - /** - * wierd constructor that is no longer supported - * @param in - * @param in1 - * @throws com.jacob.com.ComFailException - */ - public Variant(int in, double in1) { - throw new ComFailException("Not implemented"); - } - - /** - * wierd constructor that is no longer supported - * @param in - * @param in1 - * @throws com.jacob.com.ComFailException - */ - public Variant(int in, Object in1) { - throw new ComFailException("Not implemented"); - } public native short getvt(); @@ -752,14 +686,22 @@ public class Variant extends JacobObject implements java.io.Serializable { } } - // superceded by SafeArray + /** + * @deprecated superceded by SafeArray + * @return + * @throws com.jacob.com.ComNotImplementedException + */ public Variant[] toVariantArray() { - throw new ClassCastException("Not implemented"); + throw new ComNotImplementedException("Not implemented"); } - // superceded by SafeArray + /** + * @deprecated superceded by SafeArray + * @return + * @throws com.jacob.com.ComNotImplementedException + */ public Object toByteArray() { - throw new ClassCastException("Not implemented"); + throw new ComNotImplementedException("Not implemented"); } static { @@ -772,7 +714,14 @@ public class Variant extends JacobObject implements java.io.Serializable { */ private void writeObject(java.io.ObjectOutputStream oos) { try { - Save(oos); + byte[] ourBytes = SerializationWriteToBytes(); + int count = ourBytes.length; + if (JacobObject.isDebugEnabled()){ + JacobObject.debug("writing out "+count+" bytes"); + } + oos.writeInt(count); + oos.write(ourBytes); + //Save(oos); } catch (Exception e) { e.printStackTrace(); } @@ -784,7 +733,18 @@ public class Variant extends JacobObject implements java.io.Serializable { */ private void readObject(java.io.ObjectInputStream ois) { try { - Load(ois); + // Load will do this if we don't but lets do it + // from here so that the variant is set up exactly + // the same as the ones not created from a stream + init(); + int numBytes = ois.readInt(); + byte[] ourBytes = new byte[numBytes]; + if (JacobObject.isDebugEnabled()){ + JacobObject.debug("reading in "+numBytes+" bytes"); + } + ois.read(ourBytes); + SerializationReadFromBytes(ourBytes); + //Load(ois); } catch (Exception e) { e.printStackTrace(); } @@ -795,9 +755,18 @@ public class Variant extends JacobObject implements java.io.Serializable { * @return true if it is null or false if not */ public native boolean isNull(); - - public native void Save(java.io.OutputStream os) throws java.io.IOException; - - public native void Load(java.io.InputStream is) throws java.io.IOException; - + + /** + * this is supposed to create a byte array that represents the underlying + * variant object struct + */ + public 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); + } \ No newline at end of file diff --git a/unittest/com/jacob/com/ExcelEventTest.java b/unittest/com/jacob/com/ExcelEventTest.java index bc75ceb..6bfac2d 100644 --- a/unittest/com/jacob/com/ExcelEventTest.java +++ b/unittest/com/jacob/com/ExcelEventTest.java @@ -1,7 +1,6 @@ package com.jacob.com; import com.jacob.activeX.ActiveXComponent; -import com.jacob.com.ComFailException; import com.jacob.com.DispatchEvents; /** @@ -60,7 +59,7 @@ public class ExcelEventTest extends InvocationProxy { Dispatch.call(workbook, "Close", f); axc.invoke("Quit", new Variant[] {}); - } catch (ComFailException cfe) { + } catch (ComException cfe) { cfe.printStackTrace(); System.out.println("Failed to attach to " + pid + ": " + cfe.getMessage()); diff --git a/unittest/com/jacob/com/VariantSerializationTest.java b/unittest/com/jacob/com/VariantSerializationTest.java new file mode 100644 index 0000000..2396817 --- /dev/null +++ b/unittest/com/jacob/com/VariantSerializationTest.java @@ -0,0 +1,61 @@ +package com.jacob.com; + +import java.io.*; + +/** + * Verifies serialization works for variants. + * Variant serialization is BROKEN and has been since 1.7 + *

-Djava.library.path=d:/jacob/release
+ */ +class VariantSerializationTest { + + static Variant vs1 = new Variant("hi"); + static Variant vs2 = new Variant(123.456); + + public static void main(String[] args) throws Exception { + doJustSerialization(); + compareVariantBytes(); + } + + private static void compareVariantBytes() throws Exception{ + System.out.println("compareVariantBytes"); + Variant var1 = new Variant("hello"); + Variant var2 = new Variant("hello"); + byte[] var1Bytes = var1.SerializationWriteToBytes(); + byte[] var2Bytes = var2.SerializationWriteToBytes(); + for ( int i = 0 ; i < var1Bytes.length; i++){ + if (var1Bytes[i]!=var2Bytes[i]){ + System.out.println("variant strings differ at position "+i); + return; + } + } + System.out.println("two strings return identical serialization data"); + } + + private static void doJustSerialization() throws Exception { + System.out.println("doJustSerialization"); + // same thing with serialization + FileOutputStream fos; + FileInputStream fis; + fos = new FileOutputStream("foo.ser"); + ObjectOutputStream oos = new ObjectOutputStream(fos); + oos.writeObject(vs1); + //oos.writeObject(vs2); + oos.close(); + fos.close(); + + fis = new FileInputStream("foo.ser"); + ObjectInputStream ois = new ObjectInputStream(fis); + + Variant vss1 = null; + Variant vss2 = null; + + vss1 = (Variant) ois.readObject(); + //vss2 = (Variant) ois.readObject(); + ois.close(); + fis.close(); + + System.out.println(vss1); + System.out.println(vss2); + } +} diff --git a/samples/com/jacob/samples/test/variant_test.java b/unittest/com/jacob/com/VariantTest.java similarity index 83% rename from samples/com/jacob/samples/test/variant_test.java rename to unittest/com/jacob/com/VariantTest.java index f4bccd3..1e22f9f 100644 --- a/samples/com/jacob/samples/test/variant_test.java +++ b/unittest/com/jacob/com/VariantTest.java @@ -1,8 +1,9 @@ -package com.jacob.samples.test; +package com.jacob.com; -import com.jacob.com.*; - -class variant_test { +/** + * runs through some of the get and set methods on Variant + */ +class VariantTest { public static void main(String[] args) { //deprecated //System.runFinalizersOnExit(true); diff --git a/unittest/com/jacob/com/WordEventTest.java b/unittest/com/jacob/com/WordEventTest.java index 119d845..9f49a2c 100644 --- a/unittest/com/jacob/com/WordEventTest.java +++ b/unittest/com/jacob/com/WordEventTest.java @@ -1,7 +1,7 @@ package com.jacob.com; import com.jacob.activeX.ActiveXComponent; -import com.jacob.com.ComFailException; +import com.jacob.com.ComException; import com.jacob.com.DispatchEvents; /** @@ -51,7 +51,7 @@ public class WordEventTest extends InvocationProxy { } axc.invoke("Quit", new Variant[] {}); - } catch (ComFailException cfe) { + } catch (ComException cfe) { cfe.printStackTrace(); System.out.println("Failed to attach to " + pid + ": " + cfe.getMessage());