⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 variant.java

📁 Very Nice library for using ActiveX controls directly from java without heavy knowledge of JNI, simp
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
/*
 * 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 + -