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

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

There is a newer version: 2024.11.18598.20241113T125352Z-241000
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.ExFull;
import com.adobe.xfa.ut.MsgFormatPos;
import com.adobe.xfa.ut.ResId;
import com.adobe.xfa.ut.StringUtils;

/**
 * Represents an option such as those passed to
 * XFAModelFactory::setOption(). This class shouldn't be part of
 * the published XFA DOM API.
 * 
 * 
 * 
 *  
 *   Usage: an Option is generally stored as a member of the object 
 *          to which the option pertains.  An Option is created with
 *          two strings: the name of the option, and a string 
 *          representing all of the possible values to which the option
 *          can be set.  The format of the validation string is as 
 *          follows:
 *  
 *          "option1|option2|...|optionN"
 *  
 *          Each section of the string represents one possible value.
 *          It can be one of the following:
 *  
 *          "literal"  - a literal string that must match exactly 
 *                       (i.e. a keyword)
 *          "%d"       - an integer
 *          "%lf"      - a double (%lf is long-float scanf notation)
 *          "%b"       - a boolean (i.e. a "1" or a "0")
 *          "%s"       - a string
 *  
 *          Example: "default|%d|%s" represents that an option can be 
 *          either the word "default", or an integer, or a string.  
 *          Note that the order is important.  Possible matches are 
 *          considered from left to right.
 *  
 *          The caller passes the option into setValue(), which matches
 *          the option against the validation string.  In the example 
 *          above, if setValue were called with "default", then 
 *          getMatchingIndex() would return 0.  If instead setValue() 
 *          were called with "5", then getMatchingIndex() would return 
 *          1, and the caller could retrieve the value 5 from 
 *          getInteger().  Finally if a string other than "default" 
 *          were passed in, then getMatchingIndex() would return 2, and
 *          the string could be retrieved via getString().
 *  
 *          An exception is thrown if setValue is called with an 
 *          invalid option.
 *  
 *          If the option has never been set (ie. setValue() has not 
 *          been called) then getMatchingIndex() returns -1.
 *  
 *  
 * 
* * @exclude from published api. */ public final class Option { private static final int BOOL = 1; // "flatten" private static final int DOUBLE = 3; /** * OptionType is an enumeration of all the possible types of Options */ private static final int EMPTY = 0; private static final int INTEGER = 2; private static final int LITERAL = 5; private static final int STRING = 4; /** * Static routine: given a null-terminated list of pointers to Option, this * routine will look up the option called optionName in the list, and call * setValue on that option (passing optionValue and bCritical). * * If the option name contains a package name (such as "data_flatten"), this * routine will verify that it matches packageName. If it doesn't match, an * exception will be thrown. * * If the optionName is an empty string, then all the options are reset. In * this case, -1 is returned. All other parameters except for the option * list are ignored when resetting options. * * @param packageName * the name of the package that the options belong to (eg. * "data"). * @param options * the list of pointers to options. * @param optionName * the name of the option. * @param optionValue * the value of the option. * @param bCritical * disallow further modification of this option. * * @return the index into the array of the option that was set, or -1 if * optionName is an empty string. * @exception OptionWrongPackageException * @exception InvalidOptionException */ public static int setOptionByArray(String packageName, Option[] options, String optionName, String optionValue, boolean bCritical) { // validate package name, and trim it off if specified. String name; name = optionName; Option option; int index; // reset all the options if optionName is empty if (StringUtils.isEmpty(optionName)) { for (index = 0; (option = options[index]) != null; index++) { option.reset(); } return -1; } int nPackageSeparatorOffset = optionName.indexOf('_'); if (nPackageSeparatorOffset != -1) { if (nPackageSeparatorOffset == 0) throw new ExFull(ResId.OptionWrongPackageException, optionName); // package specified; verify that it's the right one if (!optionName.substring(nPackageSeparatorOffset).equals( packageName)) // wrong package throw new ExFull(ResId.OptionWrongPackageException, optionName); // package is OK; remove it from the option name name = optionName.substring(nPackageSeparatorOffset + 1); } for (index = 0; (option = options[index]) != null; index++) { if (option.getName().equals(name)) { option.setValue(optionValue, bCritical); return index; } } throw new ExFull(ResId.InvalidOptionException, optionName); } private boolean mbLocked; // true if this option is locked private int mnMatchingIndex; // index of matching section of mValidValues private String mOptionName; // name of option without package name, eg. private String mString; private int mType; private String mValidValues; // list of possible values, eg "1|0" private Object mValue; // One of: Boolean / Integer / Double /** * Copy constructor * * @param src * the Option to copy */ public Option(Option src) { mType = src.mType; mValue = src.mValue; mString = src.mString; mOptionName = src.mOptionName; mValidValues = src.mValidValues; mnMatchingIndex = src.mnMatchingIndex; mbLocked = src.mbLocked; } /** * Constructor for Option. * * @param name * the name of the new option * @param validValues * the value of the new option. */ public Option(String name, String validValues) { mOptionName = name; mValidValues = validValues; mType = EMPTY; mnMatchingIndex = -1; mbLocked = false; mValue = null; } /** * Set an option to be empty. This doesn't affect the locked flag. * */ private void empty() { mnMatchingIndex = -1; if (mType == STRING) mString = ""; mType = EMPTY; mValue = null; } /** * Compare this option object to another for equality. * * @param object * the other option * @return true if the two options are equal in value, false otherwise */ 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; Option right = (Option) object; if (mType != right.mType) return false; switch (mType) { case EMPTY: return true; case LITERAL: return mnMatchingIndex == right.mnMatchingIndex; case BOOL: return getBool() == right.getBool(); case INTEGER: return getInteger() == right.getInteger(); case DOUBLE: return getDouble() == right.getDouble(); case STRING: return getString().equals(right.getString()); default: assert false; return false; } } public int hashCode() { int hash = 17; hash = (hash * 31) ^ mType; switch (mType) { case EMPTY: break; case LITERAL: hash = (hash * 31) ^ getMatchingIndex(); break; case BOOL: hash = (hash * 31) ^ Boolean.valueOf(getBool()).hashCode(); break; case INTEGER: hash = (hash * 31) ^ getInteger(); break; case DOUBLE: { long bits = Double.doubleToLongBits(getDouble()); hash = (hash * 31) ^ (int) (bits ^ (bits >>> 32)); break; } case STRING: hash = (hash * 31) ^ getString().hashCode(); break; } return hash; } /** * Return the option type * * @return our option type. This is EMPTY if this option has not been set. * If this option has been set, the return type of getArgType will * be one of types represented by the validation string in the * constructor. */ public int getArgType() { return mType; } /** * Return the boolean value held by this option * * @return our boolean value * @exception OptionMisuseException */ public boolean getBool() { if (mType != BOOL) throw new ExFull(ResId.OptionMisuseException, getName()); // force true return value to be the usual value of true, as opposed to // the // scripting-style -1 Boolean b = (Boolean) mValue; return b.booleanValue(); } /** * Return the double value held by this option * * @return our double value * @exception OptionMisuseException */ public double getDouble() { if (mType != DOUBLE) { if (mType == INTEGER) return getInteger(); throw new ExFull(ResId.OptionMisuseException, getName()); } Double d = (Double) mValue; return d.doubleValue(); } /** * Return the integer held by this option * * @return our integer value. * @exception OptionMisuseException */ public int getInteger() { if (mType != INTEGER) throw new ExFull(ResId.OptionMisuseException, getName()); Integer i = (Integer) mValue; return i.intValue(); } /** * Return the integer held by this option * * @return the 0-based index (into validValues specified in the ructor) that * this option has been set to via setValue. Returns -1 if option * has not been set. */ public int getMatchingIndex() { return mnMatchingIndex; } /** * Return the name of this option * * @return our name (set in the ructor) */ public String getName() { return mOptionName; } /** * Return the string value held by this option * * @return our string value * @exception OptionMisuseException */ public String getString() { if (mType != STRING) throw new ExFull(ResId.OptionMisuseException, getName()); return mString; } // /** // * Find out if the option is empty // * // * @return true if the option is empty, false otherwise // */ // private boolean isEmpty() { // return mType == EMPTY; // } /** * Return whether this option has been set via setValue * * @return true if the option has been set, false if it has not. (isSet() is * equivalent to getMatchingIndex != -1). */ public boolean isSet() { return getMatchingIndex() != -1; } /** * Reset an option. This empties it and clears the locked flag. * */ public void reset() { empty(); mbLocked = false; } /** * Assign this option to a boolean * * @param b * the boolean value to take on */ private void setBool(boolean b) { empty(); mType = BOOL; mValue = Boolean.valueOf(b); } /** * Assign this option to a double * * @param d * the double value to take on */ private void setDouble(double d) { empty(); mType = DOUBLE; mValue = new Double(d); } /** * Assign this option to an integer * * @param i * the integer value to take on */ private void setInteger(int i) { empty(); mType = INTEGER; mValue = Integer.valueOf(i); } /** * Assign this option to a string * * @param s * the string value to take on */ private void setString(String s) { empty(); mType = STRING; mString = s; } /** * Set the value of this option (value is validated against validValues * specified in ructor).
*
* After setting the value, the parsed value may be read via * getInteger(), getString(), getMatchingIndex() etc. * * @param value * the value to take on * @param bCritical * disallow further modification of this option. * @exception OptionLockedException */ public void setValue(String value, boolean bCritical) { if (mbLocked) { // Value is locked; ignore request, unless the caller has specified // that they want to lock it, in which case throw an exception if // the values are not the same. if (bCritical) { Option oCheck = new Option(this); oCheck.mbLocked = false; oCheck.setValue(value, true); if (!this.equals(oCheck)) throw new ExFull(ResId.OptionLockedException, getName()); } return; } empty(); int nIndex = 0; mbLocked = bCritical; String[] tokens = mValidValues.split("\\|"); for (int i = 0; i < tokens.length; i++) { String token = tokens[i]; if (token.equals("%d")) { try { int long_value = Integer.parseInt(value); setInteger(long_value); mnMatchingIndex = nIndex; return; } catch (NumberFormatException n) { // It's not a number. continue... } } else if (token.equals("%lf")) { double double_value = Double.parseDouble(value); if (!Double.isInfinite(double_value)) setDouble(double_value); mnMatchingIndex = nIndex; return; } else if (token.equals("%s")) { setString(value); mnMatchingIndex = nIndex; return; } else if (token.equals("%b")) { // match on 1 or 0 char c = 0; if (value.length() == 1) c = value.charAt(0); if ((c == '1') || (c == '0')) { setBool(c == '1'); mnMatchingIndex = nIndex; return; } } else if (token.equals(value)) { // A literal match of a keyword. mType = LITERAL; mnMatchingIndex = nIndex; return; } nIndex++; } // Invalid value passed in; unable to match one of the valid values. mbLocked = false; MsgFormatPos oMessage = new MsgFormatPos( ResId.InvalidOptionValueException); oMessage.format(getName()); oMessage.format(value); throw new ExFull(oMessage); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy