📄 variant.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;
import java.math.BigDecimal;
import java.math.BigInteger;
/**
* 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>
* Just loading this class creates 3 variants that get added to the ROT
* <p>
* PROPVARIANT introduces new types so eventually Variant will need to be
* upgraded to support PropVariant types.
* http://blogs.msdn.com/benkaras/archive/2006/09/13/749962.aspx
* <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;
/**
* 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);
/*
* do the run time definition of DEFAULT and MISSING Have to use static
* block because of the way the initialization si done
*/
static {
com.jacob.com.Variant vtMissing = new com.jacob.com.Variant();
vtMissing.putVariantNoParam();
DEFAULT = vtMissing;
VT_MISSING = vtMissing;
}
/**
* Pointer to MS struct.
*/
int m_pVariant = 0;
/** variant's type is empty : equivalent to VB Nothing and VT_EMPTY */
public static final short VariantEmpty = 0;
/** variant's type is null : equivalent to VB Null and VT_NULL */
public static final short VariantNull = 1;
/** variant's type is short VT_I2 */
public static final short VariantShort = 2;
/** variant's type is int VT_I4, a Long in VC */
public static final short VariantInt = 3;
/** variant's type is float VT_R4 */
public static final short VariantFloat = 4;
/** variant's type is double VT_R8 */
public static final short VariantDouble = 5;
/** variant's type is currency VT_CY */
public static final short VariantCurrency = 6;
/** variant's type is date VT_DATE */
public static final short VariantDate = 7;
/** variant's type is string also known as VT_BSTR */
public static final short VariantString = 8;
/** variant's type is dispatch VT_DISPATCH */
public static final short VariantDispatch = 9;
/** variant's type is error VT_ERROR */
public static final short VariantError = 10;
/** variant's type is boolean VT_BOOL */
public static final short VariantBoolean = 11;
/** variant's type is variant it encapsulate another variant VT_VARIANT */
public static final short VariantVariant = 12;
/** variant's type is object VT_UNKNOWN */
public static final short VariantObject = 13;
/** variant's type is object VT_DECIMAL */
public static final short VariantDecimal = 14;
/** variant's type is byte VT_UI1 */
public static final short VariantByte = 17;
/**
* variant's type is 64 bit long integer VT_I8 - not yet implemented in
* Jacob because we have to decide what to do with Currency and because its
* only supported on XP and later. No win2k, NT or 2003 server.
*/
public static final short VariantLongInt = 20;
/** what is this? */
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;
/**
* @deprecated should use changeType() followed by getInt()
* @return the value of this variant as an int (after possible conversion)
*/
@Deprecated
public int toInt() {
changeType(VariantInt);
return getInt();
}
/**
* @deprecated should use changeType() followed by getDate()
* @return the value of this variant as a date (after possible conversion)
*/
@Deprecated
public double toDate() {
changeType(VariantDate);
return getDate();
}
/**
* Returns the windows time contained in this Variant as a Java Date
* converts to a date like many of the other toXXX() methods SF 959382.
* <p>
* This method added 12/2005 for possible use by jacobgen instead of its
* conversion code
* <p>
* 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
*
*/
@Deprecated
public Date toJavaDate() {
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)
*/
@Deprecated
public boolean toBoolean() {
changeType(Variant.VariantBoolean);
return getBoolean();
}
/** @return the value of this variant as an enumeration (java style) */
public native EnumVariant toEnumVariant();
/**
* This method would have returned null if the type was VT_NULL. But because
* we return null if the data is not of the right type, this method should
* have always returned null
*
* @deprecated method never did anything
*/
@Deprecated
public void getNull() {
};
/**
* Set this Variant's type to VT_NULL (the VB equivalent of NULL)
*/
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 !
*/
@Deprecated
public native Variant cloneIndirect();
/**
* @deprecated should call changeType() then getDouble()
* @return the content of this variant as a double (after possible
* conversion)
*/
@Deprecated
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
*/
@Deprecated
public long toCurrency() {
changeType(Variant.VariantCurrency);
return getCurrency();
}
/**
* @deprecated superceded by SafeArray
* @param in
* doesn't matter because this method does nothing
* @throws com.jacob.com.NotImplementedException
*/
@Deprecated
public void putVariantArray(Variant[] in) {
throw new NotImplementedException("Not implemented");
}
/**
* @deprecated superceded by SafeArray
* @return never returns anything
* @throws com.jacob.com.NotImplementedException
*/
@Deprecated
public Variant[] getVariantArray() {
throw new NotImplementedException("Not implemented");
}
/**
* Exists to support jacobgen. This would be deprecated if it weren't for
* jacobgen
*
* @deprecated superceded by "this"
* @return this same object
*/
@Deprecated
public Variant toVariant() {
return this;
}
/**
* @deprecated superceded by SafeArray
* @param in
* doesn't matter because this method does nothing
* @throws com.jacob.com.NotImplementedException
*/
@Deprecated
public void putByteArray(Object in) {
throw new NotImplementedException("Not implemented");
}
/**
* set the content of this variant to a short (VT_I2|VT_BYREF)
*
* @param 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
*/
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);
}
/**
* private JNI method called by putDecimalRef
*
* @param signum
* sign
* @param scale
* BigDecimal's scale
* @param lo
* low 32 bits
* @param mid
* middle 32 bits
* @param hi
* high 32 bits
*/
private native void putVariantDecRef(int signum, byte scale, int lo,
int mid, int hi);
/**
* Set the content of this variant to an decimal (VT_DECIMAL|VT_BYREF) This
* may throw exceptions more often than the caller expects because most
* callers don't manage the scale of their BigDecimal objects.
*
* @param in
* the BigDecimal that will be converted to VT_DECIMAL
* @throws IllegalArgumentException
* if the scale is > 28, the maximum for VT_DECIMAL
*/
public void putDecimalRef(BigDecimal in) {
// verify we aren't released
getvt();
if (in.scale() > 28) {
// should this really cast to a string and call putStringRef()?
throw new IllegalArgumentException(
"VT_DECIMAL only supports a scale of 28 and the passed"
+ " in value has a scale of " + in.scale());
} else {
int sign = in.signum();
// MS decimals always have positive values with just the sign flipped
if (in.signum() < 0){
in = in.negate();
}
byte scale = (byte) in.scale();
BigInteger unscaled = in.unscaledValue();
BigInteger shifted = unscaled.shiftRight(32);
putVariantDecRef(sign, scale, unscaled.intValue(), shifted
.intValue(), shifted.shiftRight(32).intValue());
}
}
/**
* set the content of this variant to a double (VT_R8|VT_BYREF)
*
* @param 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
*/
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) SF
* 959382
*
* @param inDate
* a Java date to be converted
* @throws IllegalArgumentException
* if inDate = null
*/
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
*/
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);
}
/**
* Puts a variant into this variant making it type VT_VARIANT. Added 1.12
* pre 6
*
* @param objectToBeWrapped
* A object that is to be referenced by this variant. If
* objectToBeWrapped is already of type Variant, then it is used.
* If objectToBeWrapped is not Variant then
* <code>new Variant(objectToBeWrapped)</code> is called and
* the result is passed into the com layer
* @throws IllegalArgumentException
* if inVariant = null or if inVariant is a Varint
*/
public void putVariant(Object objectToBeWrapped) {
if (objectToBeWrapped == null) {
throw new IllegalArgumentException(
"Cannot put null in as a variant");
} else if (objectToBeWrapped instanceof Variant) {
throw new IllegalArgumentException(
"Cannot putVariant() only accepts non jacob objects.");
} else {
Variant inVariant = new Variant(objectToBeWrapped);
putVariantVariant(inVariant);
// This could be done in Variant.cpp
if (JacobObject.isDebugEnabled()) {
JacobObject
.debug("Zeroing out enclosed Variant's ref to windows memory");
}
inVariant.m_pVariant = 0;
}
}
/**
* All VariantVariant type variants are BYREF.
*
* Set the content of this variant to a string (VT_VARIANT|VT_BYREF).
*
* Added 1.12 pre 6 - VT_VARIANT support is at an alpha level
*
* @param in
* variant to be wrapped
*
*/
private native void putVariantVariant(Variant in);
/**
* Used to get the value from a windows type of VT_VARIANT or a jacob
* Variant type of VariantVariant. Added 1.12 pre 6 - VT_VARIANT support is
* at an alpha level
*
* @return Object a java Object that represents the content of the enclosed
* Variant
*/
public Object getVariant() {
if ((this.getvt() & VariantVariant) == VariantVariant
&& (this.getvt() & VariantByref) == VariantByref) {
if (JacobObject.isDebugEnabled()) {
JacobObject.debug("About to call getVariantVariant()");
}
Variant enclosedVariant = new Variant();
int enclosedVariantMemory = getVariantVariant();
enclosedVariant.m_pVariant = enclosedVariantMemory;
Object enclosedVariantAsJava = enclosedVariant.toJavaObject();
// zero out the reference to the underlying windows memory so that
// it is still only owned in one place by one java object
// (this object of type VariantVariant)
// enclosedVariant.putEmpty(); // don't know if this would have had
// side effects
if (JacobObject.isDebugEnabled()) {
JacobObject
.debug("Zeroing out enclosed Variant's ref to windows memory");
}
enclosedVariant.m_pVariant = 0;
return enclosedVariantAsJava;
} else {
throw new IllegalStateException(
"getVariant() only legal on Variants of type VariantVariant, not "
+ this.getvt());
}
}
/**
* Returns the variant type via a native method call. Added 1.12 pre 6 -
* VT_VARIANT support is at an alpha level
*
* @return Variant one of the VT_Variant types
*/
private native int getVariantVariant();
/**
* get the content of this variant as a short
*
* @return short
*/
private native short getVariantShortRef();
/**
* get the content of this variant as an int
*
* @return int
* @throws IllegalStateException
* if variant is not of the requested type
*/
public short getShortRef() {
if ((this.getvt() & VariantShort) == VariantShort
&& (this.getvt() & VariantByref) == VariantByref) {
return getVariantShortRef();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -