All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.adobe.xfa.Arg Maven / Gradle / Ivy

There is a newer version: 2024.9.17689.20240905T073330Z-240800
Show newest version
/*
 * ADOBE CONFIDENTIAL
 *
 * Copyright 2005 Adobe Systems Incorporated All Rights Reserved.
 *
 * NOTICE: All information contained herein is, and remains the property of
 * Adobe Systems Incorporated and its suppliers, if any. The intellectual and
 * technical concepts contained herein are proprietary to Adobe Systems
 * Incorporated and its suppliers and may be covered by U.S. and Foreign
 * Patents, patents in process, and are protected by trade secret or copyright
 * law. Dissemination of this information or reproduction of this material
 * is strictly forbidden unless prior written permission is obtained from
 * Adobe Systems Incorporated.
 */
package com.adobe.xfa;


import com.adobe.xfa.ut.DoubleHolder;
import com.adobe.xfa.ut.ExFull;
import com.adobe.xfa.ut.IntegerHolder;
import com.adobe.xfa.ut.MsgFormat;
import com.adobe.xfa.ut.Numeric;
import com.adobe.xfa.ut.ResId;


/**
 * This class represents an argument to a function or a return value.
 * Instances of this class are primarily for use in scripting environments.
 */
public final class Arg {

	/**
	 * An enumeration representing the allowable argument types. Note that
	 * INVALID is NEVER assigned to an Arg. It is not used by Arg, but can be
	 * used by other code to represent an XFAArgType other than one of the
	 * "real" types.
	 */

	/**
	 * @exclude from published api.
	 */
	public static final int NULL = 2;

	/**
	 * @exclude from published api.
	 */
	public static final int BOOL = 3;

	/**
	 * @exclude from published api.
	 */
	public static final int DOUBLE = 5;

	/**
	 * @exclude from published api.
	 */
	public static final int EMPTY = 1;

	/**
	 * @exclude from published api.
	 */
	public static final int EXCEPTION = 8;

	/**
	 * @exclude from published api.
	 */
	public static final int INTEGER = 4;

	static final String gsEmpty = "Empty";

	static final String gsError = "Error:";

	static final String gsFalse = "False";

	static final String gsNull = "Null";

	static final String gsObject = "Object";

	static final String gsTrue = "True";

	static final String gsVoidPtr = "Pointer:";

	/**
	 * @exclude from published api.
	 */
	public static final int INVALID = 0;

	/**
	 * @exclude from published api.
	 */
	public static final int OBJECT = 7;

	/**
	 * @exclude from published api.
	 */
	public static final int STRING = 6;

	/**
	 * @exclude from published api.
	 */
	public static final int VOIDPTR = 9;
	
	
	private Object mArg;

	private int mType;
	
	private boolean mbIsRef = false;
	
	private boolean mbIsXFAProp = false;

	/**
	 * Instantiates an empty arg object.
	 */
	public Arg() {
		mType = EMPTY;
		//mArg = null;
	}

	/**
	 * Instantiates a copy of the given arg object.
	 * 
	 * @param src 
	 *            The Arg to be copied.
	 * 
	 * @exclude from published api.
	 */
	public Arg(Arg src) {
	    assign(src);
	}
	
	/**
     * Assigns the given arg object to this arg.
     * This is the assignment operator.
	 * 
	 * @exclude from published api.
     */
    public void assign(Arg src) {
		if (mType != EMPTY)
			empty();
		
		mType = src.mType;
		mArg = src.mArg;
		mbIsRef = src.mbIsRef;
	}

	// Returns null if not successful
	private boolean coerceToDouble(DoubleHolder n, boolean bStrongTyping /* = false */) {
		if (mType != DOUBLE) {
			if (mType == INTEGER) {
				n.value = ((Integer) mArg).doubleValue();
			    return true;
			}
			else if (mType == STRING) {
				n.value = Numeric.stringToDouble((String) mArg, false);
				if (bStrongTyping && (Double.isNaN(n.value) || Double.isInfinite(n.value)))
					return false;
				return true;
			}
			return false;
		}
		n.value = ((Double) mArg).doubleValue();
		return true;
	}

	// Returns null if not successful
	private boolean coerceToInt(IntegerHolder n) {
		if (mType != INTEGER) {
			if (mType == DOUBLE
					&& ((Double) mArg).doubleValue() == ((Double) mArg).intValue()) {
        		n.value = ((Double) mArg).intValue();
				return true;
			}
			else if (mType == STRING) {
				try {
            		n.value = Integer.parseInt((String) mArg);
    				return true;
				}
				catch (NumberFormatException e) {
    				return false;
				}
			}
			return false;
		}
		n.value = ((Integer) mArg).intValue();
		return true;
	}

	/**
	 * Set this argument to be empty
	 * 
	 * @exclude from published api.
	 */
	public void empty() {
		mArg = null;
		mType = EMPTY;
	}

	/**
	 * Comparison operator -- equality
	 * 
	 * @param object 
	 *            the object to compare
	 * @return true if this object equals the given.
	 * @exclude from published api.
	 */
	public boolean equals(Object object) {
		
		if (this == object)
			return true;
		
		// This overrides Object.equals(boolean) directly, so...
		if (object == null)
			return false;
		
		if (object.getClass() != getClass())
			return false;
		
		Arg src = (Arg) object;	
		if (mType != src.mType)
			return false;
		
		return mArg.equals(src);
	}
	
	/**
	 * Returns a hash code value for the object. This method is unsupported.
	 * @exclude from published api.
	 */
	public int hashCode() {
		int hash = 79;
		if (mArg != null)
    		hash = (hash * 31) ^ mArg.hashCode();
		hash = (hash * 31) ^ mType;
		return hash;
	}

	/**
	 * Return the argument type
	 * 
	 * @return our argument type as an XFAArgType
	 * @exclude from published api.
	 */
	public int getArgType() {
		return mType;
	}

	/**
	 * Get the value as a boolean. This involves interpreting the various types
	 * as described below. 
*
* This is a convenience function. It checks the current type of this * Arg, and returns a boolean value which best represents * the current value according to the following criteria: * *
	 * 
	 *       Current Type:    Returned Value:
	 *       EMPTY            FALSE
	 *       NULL             FALSE
	 *       BOOL,            result of getBool()
	 *       INTEGER,         TRUE if non-zero, FALSE otherwise
	 *       DOUBLE,          TRUE if non-zero, FALSE otherwise
	 *       STRING,          TRUE if string represents a non-zero number, FALSE otherwise
	 *       OBJECT,          TRUE if object is non-NULL, FALSE otherwise
	 *       EXCEPTION        FALSE
	 *  
	 * 
* * The parameter bThrowException only affects the behaviour * if the current value of this Arg is of type EXCEPTION. If * bThrowException is FALSE, then this routine will simply return FALSE. If * bThrowException is TRUE, then an exception will be thrown which contains * the error message of the exception. This can simplify processing for an * application. * * @param bThrowException * when type is EXCEPTION; if TRUE: throws an exception, if * FALSE: returns FALSE * @return the value of this Arg as a boolean * @throws the * stored exception if bThrowException is TRUE and the * current value is an exception * @exclude from published api. */ public Boolean getAsBool(boolean bThrowException /* = false */) { String sException; switch (getArgType()) { case EMPTY: case NULL: return Boolean.FALSE; case BOOL: return getBool(); case INTEGER: return Boolean.valueOf(getInteger().intValue() != 0); case DOUBLE: return Boolean.valueOf(getDouble(false) != 0.0); case STRING: String sTmp = getString(); if (sTmp.length() == 0) return Boolean.FALSE; try { int nNum = Integer.parseInt(sTmp); return Boolean.valueOf(nNum != 0); } catch (NumberFormatException n) { return Boolean.FALSE; } case OBJECT: return Boolean.valueOf(getObject() != null); case VOIDPTR: return Boolean.valueOf(getVoid(false) != null); case EXCEPTION: if (! bThrowException) return Boolean.FALSE; // arbitrary sException = getException().toString(); throw new ExFull(new MsgFormat(gsError, sException)); default: assert(false); } return Boolean.FALSE; // fake out compiler (not reached) } /** * Get the value in the form of a string. *

* This is a convenience function. It checks the current type of this * Arg, and returns a string which represents the current * value according to the following examples: * *

	 * 
	 *       Current Type:    Returned String (example):
	 *       EMPTY            "Empty"
	 *       NULL             "Null"
	 *       BOOL,            "True" or "False"
	 *       INTEGER,         "123"
	 *       DOUBLE,          "123.45"
	 *       STRING,          (the same string)
	 *       OBJECT,          "Object45" (i.e. "Object" with the ID value)
	 *       EXCEPTION        "Error: " + error message
	 *  
	 * 
* * The parameter bThrowException only affects the behaviour * if the current value of this Arg is of type EXCEPTION. If * bThrowException is FALSE, then this routine will simply return a string * representing the exception. If bThrowException is TRUE, then an exception * will be thrown which contains the error message of the exception. This * can simplify processing for an application. * * @param bThrowException * when type is EXCEPTION; if TRUE: throws an exception, if * FALSE: returns an error message * @return the value of this Arg in the form of a string * @throws the * stored exception if bThrowException is TRUE and the * current value is an exception * @exclude from published api. */ public String getAsString(boolean bThrowException /* = false */) { String sException; switch (getArgType()) { case EMPTY: return gsEmpty; case NULL: return gsNull; case BOOL: return getBool().booleanValue() ? gsTrue : gsFalse; case INTEGER: return ((Integer) mArg).toString(); case DOUBLE: return Numeric.doubleToString(((Double)mArg).doubleValue(), 8, true); case STRING: return getString(); case OBJECT: int h = System.identityHashCode(mArg); return gsObject + h; case VOIDPTR: return getVoid(false).toString(); case EXCEPTION: sException = getException().toString(); if (!bThrowException) return gsError + sException; throw new ExFull(new MsgFormat(gsError, sException)); default: assert(false); } return ""; // fake out compiler (not reached) } /** * Return the boolean value held by this argument * * @return Our boolean value * @throws ArgumentMismatchException * if the current type is not BOOL * @exclude from published api. */ public Boolean getBool() { // Support for languages such as FormCalc that use numeric values // for Booleans (just as C and C++ do). getDouble() will in turn // throw ArgumentMismatchException if it's not a double or int. if (mType != BOOL) { boolean bRet = getDouble(false) != 0.0; return Boolean.valueOf(bRet); } // force TRUE return value to be the usual value of TRUE, as opposed to // the // scripting-style -1 return ((Boolean) mArg); } /** * Return the double value held by this argument * * @param bStrongTyping apply strong typing when set. * @return our double value * @throws ArgumentMismatchException * if the current type is not DOUBLE or INTEGER. If the * current type is INTEGER, the value is automatically * converted to a double. * @exclude from published api. */ public Double getDouble(boolean bStrongTyping /* = false */) { DoubleHolder d = new DoubleHolder(); if (! coerceToDouble(d, bStrongTyping)) throw new ExFull(ResId.ArgumentMismatchException); return d.value; } /** * Return the exception held by this argument. * * @return the current exception * @throws ArgumentMismatchException * if the current type is not EXCEPTION * @exclude from published api. */ public ExFull getException() { if (mType != EXCEPTION) throw new ExFull(ResId.ArgumentMismatchException); return (ExFull) mArg; } /** * Return the integer held by this argument * * @return our integer value. * @throws ArgumentMismatchException * if the current type is cannot be converted to an integer. * If the current type is INTEGER, the integer value is * returned. If the current type is DOUBLE and the double * value has no fractional part, then the double value is * returned as an integer. If the double value has a * fractional part, ArgumentMismatchException is thrown. * @exclude from published api. */ public Integer getInteger() { IntegerHolder n = new IntegerHolder(); if (! coerceToInt(n)) throw new ExFull(ResId.ArgumentMismatchException); return n.value; } /** * Return the object held by this argument. * * @return the current Obj * @throws ArgumentMismatchException * if the current type is not OBJECT * @exclude from published api. */ public Obj getObject() { if (mType != OBJECT) throw new ExFull(ResId.ArgumentMismatchException); return (Obj) mArg; } /** * Return the string value held by this argument * * @return our string value * @throws ArgumentMismatchException * if the current type is not STRING * @exclude from published api. */ public String getString() { if (mType == STRING) return (String) mArg; else if (mType == EMPTY) return ""; else throw new ExFull(ResId.ArgumentMismatchException); } /** * Return the data object held by this argument. * * @return the data object. * @throws ExFull ArgumentMismatchException - if the current type is not EXCEPTION * @exclude from published api. */ public Object getVoid(boolean bThrowException /* = false */) { if (mType != VOIDPTR) { if (bThrowException) throw new ExFull(ResId.ArgumentMismatchException); else return null; } return mArg; } /** * Return the this Arg is compatible with a given type * * @param eType * the argument type use in the comparison * @return true if compatible else false * @exclude from published api. */ public boolean isCompatibleWith(int eType) { if (mType == eType) return true; // logic in type comparison is done in get methods DoubleHolder d = new DoubleHolder(); IntegerHolder i = new IntegerHolder(); switch (eType) { case VOIDPTR: return false; case EMPTY: return false; case NULL: return false; case OBJECT: return false; case EXCEPTION: return false; case STRING: // allow EMPTY to be coerced to the empty string return mType == EMPTY; case BOOL: return coerceToDouble(d, false); case INTEGER: return coerceToInt(i); case DOUBLE: return coerceToDouble(d, false); default: return false; } } /** * Find out if this argument is empty * * @return TRUE if the argument is empty, FALSE otherwise * @exclude from published api. */ public boolean isEmpty() { return mType == EMPTY; } /** * Assign this argument to a boolean * * @param b * the boolean value to take on * @exclude from published api. */ public void setBool(Boolean b) { empty(); mType = BOOL; mArg = b; } /** * Assign this argument to a double * * @param d * the double value to take on * @exclude from published api. */ public void setDouble(Double d) { empty(); mType = DOUBLE; mArg = d; } /** * Assign this argument to an exception (representing an error) * * @param ex * The exception to hold. * @exclude from published api. */ public void setException(ExFull ex) { empty(); mType = EXCEPTION; mArg = ex; } /** * Assign this argument to an integer * * @param i * the integer value to take on * @exclude from published api. */ public void setInteger(Integer i) { empty(); mType = INTEGER; mArg = i; } /** * Set this argument to be NULL * @exclude from published api. */ public void setNull() { empty(); mType = NULL; } /** * Assign this argument to a given XFA object * * @param obj * The XFA object to hold. * @exclude from published api. */ public void setObject(Obj obj) { setObject(obj, false); } /** * Assign this argument to a given XFA object * * @param obj The XFA object to hold. * @param bIsRef Set to true if the object is a reference/pointer to another Object. * @exclude from published api. */ public void setObject(Obj obj, boolean bIsRef /* = false */) { setObject(obj, bIsRef, false); } /** * Assign this argument to a given XFA object * * @param obj The XFA object to hold. * @param bIsRef Set to true if the object is a reference/pointer to another Object. * @exclude from published api. */ public void setObject(Obj obj, boolean bIsRef /* = false */, boolean bIsProp /*=false*/) { empty(); mType = OBJECT; mArg = obj; mbIsRef = bIsRef; mbIsXFAProp = bIsProp; } /** * Assign this argument to a string * * @param s * the string value to take on * @exclude from published api. */ public void setString(String s) { empty(); mType = STRING; mArg = s; } /** * Assign this argument to a data object.. * * @param oData * the object. * @exclude from published api. */ public void setVoid(Object oData) { empty(); mType = VOIDPTR; mArg = oData; } /** * Is the current Object a reference/pointer to another Object. * * @return True if the current object is a reference/pointer to another Object, otherwise FALSE. * @exclude from published api. */ public boolean isRefObject() { if (mType == OBJECT && mbIsRef == true) return true; return false; } /** * Is the current Object resolved through property. * * @return True if the current object is resolved through property, otherwise FALSE. * @exclude from published api. */ public boolean isXFAProperty() { if (mType == OBJECT && mbIsXFAProp == true) return true; return false; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy