Files
jlibcom/src/com/jacob/com/Variant.java

772 lines
20 KiB
Java

/*
* 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;
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.
* <p>
* 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 {
/**
* Use this constant for optional parameters
*/
public final static com.jacob.com.Variant DEFAULT;
/**
* Same than {@link #DEFAULT}
*/
public final static com.jacob.com.Variant VT_MISSING;
static {
com.jacob.com.Variant vtMissing = new com.jacob.com.Variant();
vtMissing.noParam();
DEFAULT = vtMissing;
VT_MISSING = vtMissing;
}
/**
* Use for true/false variant parameters
*/
public final static com.jacob.com.Variant VT_TRUE = new com.jacob.com.Variant(
true);
/**
* Use for true/false variant parameters
*/
public final static com.jacob.com.Variant VT_FALSE = new com.jacob.com.Variant(
false);
/**
* Pointer to MS struct.
*/
int m_pVariant = 0;
/** variant's type is empty : equivalent to VB Nothing */
public static final short VariantEmpty = 0;
/** variant's type is null : equivalent to VB Null */
public static final short VariantNull = 1;
/** variant's type is short */
public static final short VariantShort = 2;
/** variant's type is int */
public static final short VariantInt = 3;
/** variant's type is float */
public static final short VariantFloat = 4;
/** variant's type is double */
public static final short VariantDouble = 5;
/** variant's type is currency */
public static final short VariantCurrency = 6;
/** variant's type is date */
public static final short VariantDate = 7;
/** variant's type is string */
public static final short VariantString = 8;
/** variant's type is dispatch */
public static final short VariantDispatch = 9;
/** variant's type is error */
public static final short VariantError = 10;
/** variant's type is boolean */
public static final short VariantBoolean = 11;
/** variant's type is variant it encapsulate another variant */
public static final short VariantVariant = 12;
/** variant's type is object */
public static final short VariantObject = 13;
/** variant's type is byte */
public static final short VariantByte = 17;
/** @todo */
public static final short VariantTypeMask = 4095;
/** variant's type is array */
public static final short VariantArray = 8192;
/** variant's type is a reference (to IDispatch?) */
public static final short VariantByref = 16384;
/**
* @return the value of this variant as an int
* (after possible conversion)
*/
public native int toInt();
/**
* @return the value of this variant as a date
* (after possible conversion)
*/
public native double toDate();
/**
* @return the value of this variant as boolean (after possible conversion)
*/
public native boolean toBoolean();
/** @return the value of this variant as an enumeration (java style) */
public native EnumVariant toEnumVariant();
/** As far as I can tell : this does absolutely nothing */
public native void getNull();
/** Set this Variant's type to VT_NULL (the VB equivalent of NULL) */
public native void putNull();
/**
* @deprecated No longer used
* @return null !
*/
public native Variant cloneIndirect();
/** @return the content of this variant as a double */
public native double toDouble();
/**
* @return the content of this variant as a long reprensenting a monetary
* amount
*/
public native long toCurrency();
/**
* @deprecated superceded by SafeArray
* @param in doesn't matter because this method does nothing
* @throws com.jacob.com.ComNotImplementedException
*/
public void putVariantArray(Variant[] in) {
throw new ComNotImplementedException("Not implemented");
}
/**
* @deprecated superceded by SafeArray
* @return never returns anything
* @throws com.jacob.com.ComNotImplementedException
*/
public Variant[] getVariantArray() {
throw new ComNotImplementedException("Not implemented");
}
/**
* @deprecated superceded by SafeArray
* @param in doesn't matter because this method does nothing
* @throws com.jacob.com.ComNotImplementedException
*/
public void putByteArray(Object in) {
throw new ComNotImplementedException("Not implemented");
}
/**
* set the content of this variant to a short (VT_I2|VT_BYREF)
* @param in
*/
public native void putShortRef(short in);
/**
* set the content of this variant to an int (VT_I4|VT_BYREF)
* @param in
*/
public native void putIntRef(int in);
/**
* set the content of this variant to a double (VT_R8|VT_BYREF)
* @param in
*/
public native void putDoubleRef(double in);
/**
* set the content of this variant to a date (VT_DATE|VT_BYREF)
* @param in
*/
public native void putDateRef(double in);
/**
* converts a java date to a windows time and calls putDateRef(double)
* SF 959382
* @throws IllegalArgumentException if inDate = null
* @param inDate a Java date to be converted
*/
public void putDateRef(Date inDate){
if (inDate == null){
throw new IllegalArgumentException("Cannot put null in as windows date");
// do nothing
} else {
putDateRef(DateUtilities.convertDateToWindowsTime(inDate));
}
}
/**
* set the content of this variant to a string (VT_BSTR|VT_BYREF)
* @param in
*/
public native void putStringRef(String in);
/**
* get the content of this variant as a short
* @return short
*/
public native short getShortRef();
/**
* get the content of this variant as an int
* @return int
*/
public native int getIntRef();
/**
* set the content of this variant to a short (VT_I2)
* @param in
*/
public native void putShort(short in);
/**
* get the content of this variant as a short
* @return short
*/
public native short getShort();
/**
* get the content of this variant as a double
* @return double
*/
public native double getDoubleRef();
/**
* get the content of this variant as a double representing a date
* @return double
*/
public native double getDateRef();
/**
* returns the windows time contained in this Variant to a Java Date
* should return null if this is not a date reference Variant
* SF 959382
* @return java.util.Date
*/
public Date getJavaDateRef(){
double windowsDate = getDateRef();
if (windowsDate == 0){
return null;
} else {
return DateUtilities.convertWindowsTimeToDate(getDate());
}
}
/**
* get the content of this variant as a string
* @return String
*/
public native String getStringRef();
/**
* @deprecated superceded by SafeArray
* @return never returns anything
* @throws com.jacob.com.ComNotImplementedException
*/
public Object toCharArray() {
throw new ComNotImplementedException("Not implemented");
}
/**
* Clear the content of this variant
*/
public native void VariantClear();
/**
* @return the content of this variant as a Dispatch object
*/
public native Dispatch toDispatch();
/**
* this returns null
* @return ?? comment says null?
*/
public native Object clone();
/**
* attempts to return the content of this variant as a string
* @return String
*/
public native String toString();
/**
* return the int value held in this variant (fails on other types?)
* @return int
*/
public native int getInt();
/**
* return the date (as a double) value held in this variant (fails on other
* types?)
* @return double
*/
public native double getDate();
/**
* 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
*/
public Date getJavaDate(){
double windowsDate = getDate();
if (windowsDate == 0){
return null;
} else {
return DateUtilities.convertWindowsTimeToDate(getDate());
}
}
/**
* set the value of this variant
* @param in
*/
public native void putInt(int in);
/**
* set the value of this variant
* @param in
*/
public native void putDate(double in);
/**
* converts a java date to a windows time and calls putDate(double)
* SF 959382
* @throws IllegalArgumentException if inDate = null
* @param inDate a Java date to be converted
*/
public void putDate(Date inDate){
if (inDate == null){
throw new IllegalArgumentException("Cannot put null in as windows date");
// do nothing
} else {
putDate(DateUtilities.convertDateToWindowsTime(inDate));
}
}
/**
* attempts to return the content of this variant as a double
* (after possible conversion)
* @return byte
*/
public native byte toByte();
/**
* same as {@link #toDispatch()}
* @return this object as a dispatch
*/
public Object getDispatch() {
return toDispatch();
}
/**
* same as {@link #putObject(Object)}
* @param in
*/
public void putDispatch(Object in) {
putObject(in);
}
/**
*
* @return the value in this Variant as a boolean, null if not a boolean
*/
public native boolean getBoolean();
/**
*
* @return the value in this Variant as a byte, null if not a byte
*/
public native byte getByte();
public native void putBoolean(boolean in);
public native void putByte(byte in);
public native int toError();
public Object toObject() {
return toDispatch();
}
public native void getEmpty();
public native void putEmpty();
public native int getError();
public native void putError(int in);
public native double getDouble();
public native void putCurrency(long in);
/** puts an object into the */
public native void putObject(Object in);
public native void putDouble(double in);
/**
*
* @return the value in this Variant as a long, null if not a long
*/
public native long getCurrency();
public native void putFloatRef(float in);
public native void putCurrencyRef(long in);
public native void putErrorRef(int in);
public native void putBooleanRef(boolean in);
public void putObjectRef(Object in) {
putObject(in);
}
public native void putByteRef(byte in);
public native String getString();
public native void putString(String in);
public native float getFloatRef();
public native long getCurrencyRef();
public native int getErrorRef();
public native boolean getBooleanRef();
public native byte getByteRef();
/**
* attempts to return the contents of this variant as a float
* (after possible conversion)
* @return float
*/
public native float toFloat();
/**
* 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
*/
public SafeArray toSafeArray() {
return toSafeArray(true);
}
public native SafeArray toSafeArray(boolean deepCopy);
public native void putSafeArrayRef(SafeArray in);
public native void putSafeArray(SafeArray in);
public native void noParam();
/**
* @deprecated superceded by SafeArray
* @throws com.jacob.com.ComNotImplementedException
*/
public void putCharArray(Object in) {
throw new ComNotImplementedException("Not implemented");
}
public native float getFloat();
public native void putFloat(float in);
public void putDispatchRef(Object in) {
putDispatch(in);
}
public Object getDispatchRef() {
return getDispatch();
}
/**
* @deprecated superceded by SafeArray
* @throws com.jacob.com.ComNotImplementedException
*/
public void putVariantArrayRef(Variant[] in) {
throw new ComNotImplementedException("Not implemented");
}
/**
* @deprecated superceded by SafeArray
* @throws com.jacob.com.ComNotImplementedException
*/
public Variant[] getVariantArrayRef() {
throw new ComNotImplementedException("Not implemented");
}
public native void changeType(short in);
public void changeType(int in) {
changeType((short) in);
}
public Object toScriptObject() {
return toDispatch();
}
/**
* public constructor
*/
public Variant() {
init();
putEmpty();
if (isDebugEnabled()) {
debug("Variant: " + "create " + this );
}
}
/**
* Constructor that accepts a primitive rather than an object
* @param in
*/
public Variant(int in) {
init();
putInt(in);
}
/**
* Constructor that accepts a primitive rather than an object
* @param in
*/
public Variant(double in) {
init();
putDouble(in);
}
/**
* Constructor that accepts a primitive rather than an object
* @param in
*/
public Variant(boolean in) {
init();
putBoolean(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);
}
/**
* constructor that accepts the data object and informaton about
* whether this is by reference or not
* @param o
* @param fByRef
*/
public Variant(Object o, boolean fByRef) {
init();
if (o == null) {
putEmpty();
} else if (o instanceof Integer) {
if (fByRef)
putIntRef(((Integer) o).intValue());
else
putInt(((Integer) o).intValue());
} else if (o instanceof String) {
if (fByRef)
putStringRef((String) o);
else
putString((String) o);
} else if (o instanceof Boolean) {
if (fByRef)
putBooleanRef(((Boolean) o).booleanValue());
else
putBoolean(((Boolean) o).booleanValue());
} else if (o instanceof Double) {
if (fByRef)
putDoubleRef(((Double) o).doubleValue());
else
putDouble(((Double) o).doubleValue());
} else if (o instanceof Float) {
if (fByRef)
putFloatRef(((Float) o).floatValue());
else
putFloat(((Float) o).floatValue());
} else if (o instanceof SafeArray) {
if (fByRef)
putSafeArrayRef((SafeArray) o);
else
putSafeArray((SafeArray) o);
} else {
if (fByRef)
putObjectRef(o);
else
putObject(o);
}
}
public native short getvt();
/**
* attempts tor return the contents of this Variant as a short
* (after possible conversion)
* @return short
*/
public native short toShort();
/**
* now private so only this object can asccess was: call this to explicitly
* release the com object before gc
*
*/
private native void release();
protected native void init();
/*
* (non-Javadoc)
*
* @see java.lang.Object#finalize()
*/
protected void finalize() {
super.safeRelease();
safeRelease();
}
/*
* (non-Javadoc)
*
* @see com.jacob.com.JacobObject#safeRelease()
*/
public void safeRelease() {
super.safeRelease();
if (m_pVariant != 0) {
release();
m_pVariant = 0;
} else {
// looks like a double release
// this should almost always happen due to gc
// after someone has called ComThread.Release
if (isDebugEnabled()) {
debug("Variant: " + this.hashCode()
+ " double release");
//Throwable x = new Throwable();
//x.printStackTrace();
}
}
}
/**
* @deprecated superceded by SafeArray
* @return
* @throws com.jacob.com.ComNotImplementedException
*/
public Variant[] toVariantArray() {
throw new ComNotImplementedException("Not implemented");
}
/**
* @deprecated superceded by SafeArray
* @return
* @throws com.jacob.com.ComNotImplementedException
*/
public Object toByteArray() {
throw new ComNotImplementedException("Not implemented");
}
static {
System.loadLibrary("jacob");
}
/**
* custom serialization support
* @param oos
*/
private void writeObject(java.io.ObjectOutputStream oos) {
try {
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();
}
}
/**
* custom serialization support
* @param ois
*/
private void readObject(java.io.ObjectInputStream ois) {
try {
// 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();
}
}
/**
* is the variant null or empty or error or null disp
* @return true if it is null or false if not
*/
public native boolean isNull();
/**
* 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);
}