com.adobe.xfa.formcalc.BuiltinLogical Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of aem-sdk-api Show documentation
Show all versions of aem-sdk-api Show documentation
The Adobe Experience Manager SDK
The newest version!
/*
* ADOBE CONFIDENTIAL
*
* Copyright 2007 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.formcalc;
import java.text.Collator;
import com.adobe.xfa.ut.StringUtils;
/**
* This class defines static methods to implement
* the FormCalc logical calculations.
*
* L O G I C A L F U N C T I O N S
* choose, if, oneof, throw, within.
*
* @author Mike P. Tardif
*
* @exclude from published api.
*/
final class BuiltinLogical {
/*
* Disallow instances of this class.
*/
private BuiltinLogical() {
}
/*
* Choose
* This function returns a choosen a string from a given set of values.
*/
static void Choose(CalcParser oParser, CalcSymbol[] oArgSym) {
final int nArgs = oArgSym.length;
CalcSymbol oRetSym = null;
try {
//
// check the number of args vs the number required.
//
Builtins.minArgs(nArgs, 2);
//
// check for error-valued, return-valued and null-valued args.
//
Builtins.limitExceptionArgs(oArgSym);
Builtins.limitNullArgs(oParser, 1, oArgSym);
//
// evaluate the given args.
//
int nVal = (int) oParser.getNumeric(oArgSym[0]);
//
// choose the requested string.
//
for (int i = 1; i < nArgs; ) {
if (oArgSym[i].getType() == CalcSymbol.TypeAccessor) {
CalcSymbol[] oSym = oParser.moScriptHost.getItemValue(
oArgSym[i].getName(), oArgSym[i].getObjValues());
int nSyms = oSym.length;
for (int j = 0; j < nSyms; j++) {
if (i + j == nVal) {
oRetSym = new CalcSymbol(oSym[j]);
break;
}
}
for (int j = nSyms - 1; j >=0; j--)
CalcSymbol.delete(oSym[j], oParser);
i += nSyms;
}
else {
if (i == nVal) {
oRetSym = new CalcSymbol(oArgSym[i]);
}
i += 1;
}
if (oRetSym != null) {
break;
}
}
//
// if index not found the null value.
//
if (oRetSym == null) {
oRetSym = new CalcSymbol("");
}
} catch (CalcException e) {
oRetSym = e.getSymbol();
if (oRetSym.getType() != CalcSymbol.TypeNull)
oParser.mbInThrow = true;
}
//
// push the result on the stack.
//
oParser.mStack.push(oRetSym);
}
/*
* If
* This function returns values conditionally based on the value of
* a given number.
*/
static void If(CalcParser oParser, CalcSymbol[] oArgSym) {
final int nArgs = oArgSym.length;
CalcSymbol oRetSym = null;
try {
//
// check the number of args vs the number required.
//
Builtins.minArgs(nArgs, 2);
Builtins.maxArgs(nArgs, 3);
//
// check for error-valued, return-valued and null-valued args.
//
Builtins.limitExceptionArgs(oArgSym);
Builtins.limitNullArgs(oParser, 1, oArgSym);
//
// evaluate the given args.
//
double nVal = oParser.getNumeric(oArgSym[0]);
CalcSymbol oSym1 = new CalcSymbol(oArgSym[1]);
oParser.getNumeric(oSym1);
CalcSymbol oSym2 = null;
if (nArgs > 2) {
oSym2 = new CalcSymbol(oArgSym[2]);
oParser.getNumeric(oSym2);
}
else {
oSym2 = new CalcSymbol("");
}
if (nVal != 0.) {
oRetSym = oSym1;
CalcSymbol.delete(oSym2, oParser);
}
else {
oRetSym = oSym2;
CalcSymbol.delete(oSym1, oParser);
}
} catch (CalcException e) {
oRetSym = e.getSymbol();
if (oRetSym.getType() != CalcSymbol.TypeNull)
oParser.mbInThrow = true;
}
//
// push the result on the stack.
//
oParser.mStack.push(oRetSym);
}
/*
* Oneof
* This function returns true, a.k.a., 1, if the first given value
* matches any of the remaining given set of values.
*/
static void Oneof(CalcParser oParser, CalcSymbol[] oArgSym) {
final int nArgs = oArgSym.length;
CalcSymbol oRetSym = null;
try {
//
// check the number of args vs the number required.
//
Builtins.minArgs(nArgs, 2);
//
// check for error-valued and return-valued args.
//
Builtins.limitExceptionArgs(oArgSym);
//
// determine if one of the given set.
//
oRetSym = computeOneof(oParser, oArgSym);
} catch (CalcException e) {
oRetSym = e.getSymbol();
if (oRetSym.getType() != CalcSymbol.TypeNull)
oParser.mbInThrow = true;
}
//
// push the result on the stack.
//
oParser.mStack.push(oRetSym);
}
/*
* Throw
* This function throws the given value and the empty string if no
* value is given.
*/
static void Throw(CalcParser oParser, CalcSymbol[] oArgSym) {
final int nArgs = oArgSym.length;
CalcSymbol oRetSym = null;
try {
//
// check the number of args vs the number required.
//
Builtins.maxArgs(nArgs, 1);
//
// check for error-valued and return-valued args.
//
Builtins.limitExceptionArgs(oArgSym);
//
// convert the given arg to string and return it.
//
String sVal = (nArgs > 0) ? oParser.getString(oArgSym[0])
: "";
oRetSym = new CalcSymbol(sVal);
oRetSym.setType(CalcSymbol.TypeReturn);
} catch (CalcException e) {
oRetSym = e.getSymbol();
}
//
// push the result on the stack.
//
oParser.mbInThrow = true;
oParser.mStack.push(oRetSym);
}
/*
* Within
* This function returns true, a.k.a., 1, if the first given value
* is within the given bound values.
*/
static void Within(CalcParser oParser, CalcSymbol[] oArgSym) {
final int nArgs = oArgSym.length;
CalcSymbol oRetSym = null;
try {
//
// check the number of args vs the number required.
//
Builtins.minArgs(nArgs, 3);
Builtins.maxArgs(nArgs, 3);
//
// check for error-valued, return-valued and null-valued args.
//
Builtins.limitExceptionArgs(oArgSym);
Builtins.limitNullArgs(oParser, 1, oArgSym);
//
// determine if within the given bounds.
//
oRetSym = computeWithin(oParser, oArgSym);
} catch (CalcException e) {
oRetSym = e.getSymbol();
if (oRetSym.getType() != CalcSymbol.TypeNull)
oParser.mbInThrow = true;
}
//
// push the result on the stack.
//
oParser.mStack.push(oRetSym);
}
static CalcSymbol computeOneof(CalcParser oParser, CalcSymbol[] oArgSym) {
final int nArgs = oArgSym.length;
CalcSymbol oRetSym = null;
try {
boolean bOneof = false;
int fType = oArgSym[0].getType();
//
// determine if the first given argument matches any of the
// given set of values.
//
if (fType == CalcSymbol.TypeAccessor) {
CalcSymbol[] oSym
= oParser.moScriptHost.getItemValue(oArgSym[0].getName(),
oArgSym[0].getObjValues());
CalcSymbol oTmpSym = oArgSym[0];
oArgSym[0] = oSym[0];
CalcSymbol oOneof = computeOneof(oParser, oArgSym);
if (oParser.getNumeric(oOneof) == 1.) {
bOneof = true;
}
CalcSymbol.delete(oOneof, oParser);
oArgSym[0] = oTmpSym;
for (int j = oSym.length - 1; j >=0; j--)
CalcSymbol.delete(oSym[j], oParser);
}
else if (fType == CalcSymbol.TypeDouble) {
double nVal = oParser.getNumeric(oArgSym[0]);
for (int i = 1; i < nArgs; i++) {
if (oArgSym[i].getType() == CalcSymbol.TypeAccessor) {
CalcSymbol[] oSym = oParser.moScriptHost.getItemValue(
oArgSym[i].getName(), oArgSym[i].getObjValues());
int nSyms = oSym.length;
for (int j = 0; j < nSyms; j++) {
if (nVal == oParser.getNumeric(oSym[j])) {
bOneof = true;
break;
}
}
for (int j = oSym.length - 1; j >=0; j--)
CalcSymbol.delete(oSym[j], oParser);
}
else {
if (nVal == oParser.getNumeric(oArgSym[i])) {
bOneof = true;
}
}
if (bOneof) {
break;
}
}
}
else if (fType == CalcSymbol.TypeString
|| fType == CalcSymbol.TypeVariable) {
String sVal = oParser.getString(oArgSym[0]);
for (int i = 1; i < nArgs; i++) {
if (oArgSym[i].getType() == CalcSymbol.TypeAccessor) {
CalcSymbol[] oSym = oParser.moScriptHost.getItemValue(
oArgSym[i].getName(), oArgSym[i].getObjValues());
int nSyms = oSym.length;
for (int j = 0; j < nSyms; j++) {
if (sVal.equals(oParser.getString(oSym[j]))) {
bOneof = true;
break;
}
}
for (int j = oSym.length - 1; j >=0; j--)
CalcSymbol.delete(oSym[j], oParser);
}
else {
if (sVal.equals(oParser.getString(oArgSym[i]))) {
bOneof = true;
}
}
if (bOneof) {
break;
}
}
}
else if (fType == CalcSymbol.TypeNull) {
for (int i = 1; i < nArgs; i++) {
if (oArgSym[i].getType() == CalcSymbol.TypeAccessor) {
CalcSymbol[] oSym = oParser.moScriptHost.getItemValue(
oArgSym[i].getName(), oArgSym[i].getObjValues());
int nSyms = oSym.length;
for (int j = 0; j < nSyms; j++) {
if (fType == oSym[j].getType()) {
bOneof = true;
break;
}
}
for (int j = nSyms - 1; j >=0; j--)
CalcSymbol.delete(oSym[j], oParser);
}
else {
if (fType == oArgSym[i].getType()) {
bOneof = true;
}
}
if (bOneof) {
break;
}
}
}
else /* if (fType == CalcSymbol.TypeReturn
|| fType == CalcSymbol.TypeError) */ {
throw new CalcException(oArgSym[0]);
}
oRetSym = new CalcSymbol(bOneof ? 1. : 0.);
} catch (CalcException e) {
oRetSym = e.getSymbol();
if (oRetSym.getType() != CalcSymbol.TypeNull)
oParser.mbInThrow = true;
}
return oRetSym;
}
static CalcSymbol computeWithin(CalcParser oParser, CalcSymbol[] oArgSym) {
CalcSymbol oRetSym = null;
try {
boolean bWithin = false;
int fType = oArgSym[0].getType();
//
// determine if the first given argument matches any of the
// given set of values.
//
if (fType == CalcSymbol.TypeAccessor) {
CalcSymbol[] oSym = oParser.moScriptHost.getItemValue(
oArgSym[0].getName(), oArgSym[0].getObjValues());
CalcSymbol oTmpSym = oArgSym[0];
oArgSym[0] = oSym[0];
CalcSymbol oWithin = computeWithin(oParser, oArgSym);
if (oParser.getNumeric(oWithin) == 1.) {
bWithin = true;
}
CalcSymbol.delete(oWithin, oParser);
oArgSym[0] = oTmpSym;
for (int j = oSym.length - 1; j >=0; j--)
CalcSymbol.delete(oSym[j], oParser);
}
else if (oArgSym[0].isNumeric()) {
double nVal = oParser.getNumeric(oArgSym[0]);
double nValLo = oParser.getNumeric(oArgSym[1]);
double nValHi = oParser.getNumeric(oArgSym[2]);
if (nValLo <= nVal && nVal <= nValHi) {
bWithin = true;
}
}
else if (fType == CalcSymbol.TypeString
|| fType == CalcSymbol.TypeVariable) {
String sVal = oParser.getString(oArgSym[0]);
String sValLo = oParser.getString(oArgSym[1]);
String sValHi = oParser.getString(oArgSym[2]);
Collator oCol = Collator.getInstance();
if (oCol.compare(sVal, sValLo) >= 0
&& oCol.compare(sVal, sValHi) <= 0) {
bWithin = true;
}
}
oRetSym = new CalcSymbol(bWithin ? 1. : 0.);
} catch (CalcException e) {
oRetSym = e.getSymbol();
if (oRetSym.getType() != CalcSymbol.TypeNull)
oParser.mbInThrow = true;
}
return oRetSym;
}
/*
* Exists
* This function returns true, a.k.a., 1, if the given argument
* is an accessor reference to an existing object.
*/
static void Exists(CalcParser oParser, CalcSymbol[] oArgSym) {
final int nArgs = oArgSym.length;
CalcSymbol oRetSym = null;
try {
//
// check the number of args vs the number required.
//
Builtins.minArgs(nArgs, 1);
Builtins.maxArgs(nArgs, 1);
//
// determine if within the given arg is null.
//
CalcSymbol oSymIn = new CalcSymbol(oArgSym[0]);
int nRetVal = 1;
switch (oSymIn.getType()) {
case CalcSymbol.TypeAccessor:
if (oSymIn.getName().indexOf('*') >= 0) { // more precisely, "[*]"
CalcSymbol.delete(oSymIn, oParser);
throw new CalcException();
}
if (! isObject(oParser, oSymIn))
nRetVal = 0;
break;
case CalcSymbol.TypeReference:
if (oSymIn.getObjValue() == null)
nRetVal = 0;
break;
case CalcSymbol.TypeNull:
case CalcSymbol.TypeDouble:
case CalcSymbol.TypeString:
case CalcSymbol.TypeVariable:
nRetVal = 0;
break;
case CalcSymbol.TypeError:
case CalcSymbol.TypeReturn:
default:
CalcException e = new CalcException(oSymIn);
CalcSymbol.delete(oSymIn, oParser);
throw e;
}
CalcSymbol.delete(oSymIn, oParser);
oRetSym = new CalcSymbol(nRetVal);
} catch (CalcException e) {
oRetSym = e.getSymbol();
if (oRetSym.getType() != CalcSymbol.TypeNull)
oParser.mbInThrow = true;
}
//
// push the result on the stack.
//
oParser.mStack.push(oRetSym);
}
/*
* HasValue
* This function returns true, a.k.a., 1, if the given value
* is not null, and not empty.
*/
static void HasValue(CalcParser oParser, CalcSymbol[] oArgSym) {
final int nArgs = oArgSym.length;
CalcSymbol oRetSym = null;
try {
//
// check the number of args vs the number required.
//
Builtins.minArgs(nArgs, 1);
Builtins.maxArgs(nArgs, 1);
//
// check for error-valued and return-valued args.
//
Builtins.limitExceptionArgs(oArgSym);
//
// determine if given string is empty.
//
String s = oParser.getString(oArgSym[0]).trim();
oRetSym = new CalcSymbol(StringUtils.isEmpty(s) ? 0. : 1.);
} catch (CalcException e) {
oRetSym = e.getSymbol();
if (oRetSym.getType() != CalcSymbol.TypeNull)
oParser.mbInThrow = true;
}
//
// push the result on the stack.
//
oParser.mStack.push(oRetSym);
}
static boolean isObject(CalcParser oParser, CalcSymbol oArgSym) {
try {
CalcSymbol[] oSym = oParser.moScriptHost.getItemValue(
oArgSym.getName(), oArgSym.getObjValues());
for (int j = oSym.length - 1; j >=0; j--)
CalcSymbol.delete(oSym[j], oParser);
return true;
} catch (CalcException e) {
try {
oParser.moScriptHost.getItem(oArgSym.getName(),
oArgSym.getObjValues());
return true;
} catch (CalcException f) {
}
}
return false;
}
}