com.adobe.xfa.Obj 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 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.Assertions;
import com.adobe.xfa.ut.ExFull;
import com.adobe.xfa.ut.FindBugsSuppress;
import com.adobe.xfa.ut.MsgFormat;
import com.adobe.xfa.ut.MsgFormatPos;
import com.adobe.xfa.ut.Peer;
import com.adobe.xfa.ut.PeerImpl;
import com.adobe.xfa.ut.ResId;
import com.adobe.xfa.ut.StringUtils;
/**
* A base class to represent all XFA objects, templates and data.
* The methods defined in this class are primarily for use in scripting environments.
*/
public abstract class Obj implements Peer {
private PeerImpl mPeers;
private String maClassName; // interned
private int meClassTag; // Default class tag XFA.INVALID_ELEMENT indicates we're not part
/**
* @exclude from published api.
*/
public Obj() {
maClassName = null;
meClassTag = XFA.INVALID_ELEMENT;
}
/**
* @exclude from published api.
*/
final public void addPeer(Peer poPeerNode) {
if (mPeers == null) {
mPeers = new PeerImpl(this);
}
mPeers.addPeer(poPeerNode);
}
/**
* @exclude from published api.
*/
final public void addPeeredNode(Peer poPeer) {
if (mPeers == null) {
mPeers = new PeerImpl(this);
}
mPeers.addPeeredNode(poPeer);
}
/**
* @exclude from published api.
*/
final public void clearPeers() {
if (mPeers != null)
mPeers.clearPeers();
}
/**
* @exclude from published api.
*/
final public void deafen() {
if (mPeers == null) {
mPeers = new PeerImpl(this);
}
mPeers.deafen();
}
/**
* recursive method, Find the function description
* @param table
* @param sName the function name.
*
* @exclude from published api.
*/
private ScriptFuncObj findScriptFunc(ScriptTable table, String sName) {
while (table != null) {
// ensure the script table has a listing for functions
if (table.mFuncTable != null) {
// loop through until you find a property that matches the name
final ScriptFuncObj[] funcTable = table.mFuncTable;
for (int i = 0; i < funcTable.length; i++) {
final ScriptFuncObj funcObj = funcTable[i];
if (sName.equals(funcObj.getName())) {
return funcObj;
}
}
}
// no match found, search parent class
table = table.mParentClass;
}
return null;
}
/**
* recursive method, Find the property description
* @param table
* @param sName the property name
*
* @exclude from published api.
*/
private ScriptPropObj findScriptProp(ScriptTable table, String sName) {
while (table != null) {
// ensure the script table has a listing for properties
if (table.mPropTable != null) {
// loop through until you find a property that matches the name
final ScriptPropObj[] propTable = table.mPropTable;
for (int i = 0; i < propTable.length; i++) {
final ScriptPropObj propObj = propTable[i];
if (sName.equals(propObj.getName() == null ? "" : propObj.getName()))
return propObj;
}
}
// no match found, search parent class
table = table.mParentClass;
}
return null;
}
/**
* Set the class name and class tag for this node instance.
* @param sClassName This String must be interned.
* @param eClassTag
*
* @exclude from published api.
*/
@FindBugsSuppress(code="ES")
public final void setClass( String sClassName, int eClassTag ) {
if (Assertions.isEnabled) if ( sClassName != null ) assert(sClassName == sClassName.intern());
maClassName = sClassName;
meClassTag = eClassTag;
}
/**
* @exclude from published api.
*/
public final void setClassTag( int eClassTag ) {
meClassTag = eClassTag;
}
/**
* @exclude from published api.
*/
public final int getClassTag() {
return meClassTag;
}
/**
* Returns the atomic name of this element's class.
* @return the class name as an interned string.
*
* @exclude from published api.
*/
public /*final*/ String getClassAtom() {
// assert maClassName != null;
return maClassName;
}
/**
* Gets the name of this object's class.
* Overriden by derived classes such as Element that have a local name
* that may be returned instead.
* @return the class name.
*
* @exclude from published api.
*/
public String getClassName() {
return getClassAtom();
}
/**
* if bPeek, return a function in oDesc that won't create any objects if
* called, and return FALSE if the property isn't specified.
*
* @exclude from published api.
*/
protected ScriptDynamicPropObj getDynamicScriptProp(String sPropertyName, boolean bPropertyOverride, boolean bPeek) {
return null;
}
/**
* @param bCreate
* if true, create if the map doesn't exist.
* @return The event table
*
* @exclude from published api.
*/
protected EventManager.EventTable getEventTable(boolean bCreate) {
return null;
}
/**
* Gets the requested peer.
*
* @param nPeer
* the 0-based position of the peer to retrieve.
* @return the peer at the requested position. When there are not more peers
* to return, this will return a null object.
*
* @exclude from published api.
*/
final public Peer getPeer(int nPeer /* =0 */) {
if (mPeers == null) {
return null;
}
return mPeers.getPeer(nPeer);
}
/**
* Gets the information on a script method.
* @param sName the name of the method
* @return the script function object or null if not found.
*
* @exclude from published api.
*/
public ScriptFuncObj getScriptMethodInfo(String sName) {
return findScriptFunc(getScriptThis().getScriptTable(), sName);
}
/**
* @param sPropertyName
* @return the script property with the specified name, or null if not found.
*
* @exclude from published api.
*/
protected ScriptPropObj getScriptProp(String sPropertyName) {
return findScriptProp(getScriptTable(), sPropertyName);
}
/**
* @exclude from published api.
*/
public boolean getScriptProperty(Arg retValue,
String sPropertyName,
DependencyTracker dependencyTracker /* = null */,
boolean bPeek /* = false */,
boolean bSuppressExceptions /* = false */) {
// bPropertyOverride(#sPropertyName) means don't hunt for child nodes by name
// only get xfaproperty or child element(based on classname) or script property
boolean bPropertyOverride = sPropertyName.startsWith("#");
String sPropName;
if (bPropertyOverride)
sPropName = sPropertyName.substring(1); // Skip over "#"
else
sPropName = sPropertyName;
// first add any virtual dependencies
if (dependencyTracker != null)
dependencyTracker.addVirtualDependency(this, sPropertyName);
Obj scriptThis = getScriptThis();
boolean bGotDynamicScriptProp = false;
boolean bHasDynamicProp = false;
if (sPropName.length() != 0) {
ScriptDynamicPropObj desc = scriptThis.getDynamicScriptProp(sPropName, bPropertyOverride, bPeek);
if (desc != null) {
assert desc.hasGetter();
if (!validateUsage(desc.getXFAVersion(), desc.getAvailability(), false)) {
final boolean bIsFatal = validateUsageFailedIsFatal(desc.getXFAVersion(), desc.getAvailability());
if (bIsFatal && bSuppressExceptions)
return false;
if (bIsFatal) {
MsgFormatPos message = new MsgFormatPos(ResId.InvalidGetPropertyException);
message.format(scriptThis.getClassAtom());
message.format(sPropName);
retValue.setException(new ExFull(message));
return true;
}
else { // warn
MsgFormatPos reason = new MsgFormatPos(ResId.InvalidScriptVersionException);
reason.format(getClassAtom());
reason.format(sPropName);
sendMessenge(new ExFull(reason), LogMessage.MSG_WARNING);
}
}
bHasDynamicProp = true;
bGotDynamicScriptProp = desc.invokeGetProp(this, retValue, sPropName);
}
}
if (! bGotDynamicScriptProp) {
ScriptPropObj prop = getScriptProp(sPropName);
if (prop != null && prop.hasGetter()) {
if (!validateUsage(prop.getXFAVersion(), prop.getAvailability(), false)) {
final boolean bIsFatal = validateUsageFailedIsFatal(prop.getXFAVersion(), prop.getAvailability());
if (bIsFatal && bSuppressExceptions)
return false;
if (bIsFatal) {
MsgFormatPos message = new MsgFormatPos(ResId.InvalidGetPropertyException);
message.format(scriptThis.getClassAtom());
message.format(sPropName);
retValue.setException(new ExFull(message));
}
else {
MsgFormatPos reason = new MsgFormatPos(ResId.InvalidScriptVersionException);
reason.format(getClassAtom());
reason.format(sPropName);
sendMessenge(new ExFull(reason), LogMessage.MSG_WARNING);
}
}
prop.invokeGetProp(this, retValue, dependencyTracker);
}
else if (prop != null && bHasDynamicProp) {
// Don't suppress because the user needs to know they are trying get a property
// with only a set function
MsgFormatPos message = new MsgFormatPos(ResId.InvalidGetPropertyException);
message.format(scriptThis.getClassAtom());
message.format(sPropName);
retValue.setException(new ExFull(message));
}
else {
if (bSuppressExceptions)
return false;
if (sPropName.length() == 0) {
// default property
MsgFormatPos message = new MsgFormatPos(
ResId.NoDefaultGetPropertyException, getClassAtom());
retValue.setException(new ExFull(message));
} else {
MsgFormatPos message = new MsgFormatPos(
ResId.InvalidGetPropertyException, getClassAtom());
message.format(sPropName);
retValue.setException(new ExFull(message));
}
}
}
// track dependencies if required
if (dependencyTracker != null) {
int eType = retValue.getArgType();
if (eType != Arg.EXCEPTION)
dependencyTracker.addDependency(this);
}
return true;
}
/**
* @exclude from published api.
*/
public ScriptTable getScriptTable() {
return ObjScript.getScriptTable();
}
/**
* Gets the object to be used in concert with getScriptTable() etc.
* It's almost always "this", but it needs to be overridable to support the $record
* pseudomodel, which redirects all script properties to the current record. Simply
* overriding getScriptTable and redirecting that call to the current record doesn't
* work, because when a callback function is invoked, the supplied object pointer
* would be the pseudo model, not the record.
*
* @exclude from published api.
*/
public Obj getScriptThis() {
return this;
}
/**
* Call a scripting function (method).
*
* @param sFunctionName
* The name of the function/method to call. If this parameter is
* an empty string, then an attempt is made to invoke a default
* function.
* @param parameters
* an array of parameters to the method.
* @return the return value of the function.
* @exception ResId.InvalidMethodException
* if the function name is unknown.
* @exception ResId.BadParamCountException
* if the number of parameters in nParamCount is not valid
* for the specified fucntion.
* @exception ResId.ArgumentMismatchException
* if one or more of the argument types in pParameters is
* incorrect for the specified function.
* @exception ResId.NoDefaultMethodException
* if sFunctionName is an empty string, and the object
* doesn't have a default function.
*
* @exclude from published api.
*/
public boolean invokeFunction(Arg retValue,
String sFunctionName,
Arg[] parameters,
DependencyTracker dependencyTracker /* = null */,
boolean bSuppressExceptions /* = false */) {
Obj scriptThis = getScriptThis();
ScriptFuncObj func = getScriptMethodInfo(sFunctionName);
if (func != null) {
if (!validateUsage(func.getXFAVersion(), func.getAvailability(), false)) {
final boolean bIsFatal = validateUsageFailedIsFatal(func.getXFAVersion(), func.getAvailability());
if (bIsFatal && bSuppressExceptions)
return false;
MsgFormatPos reason = new MsgFormatPos(ResId.InvalidScriptVersionException);
reason.format(getClassAtom());
reason.format(sFunctionName);
if (bIsFatal)
throw new ExFull(reason);
else // warn
sendMessenge(new ExFull(reason), LogMessage.MSG_WARNING);
}
//
// check that we have a min num of params
//
if (parameters.length < func.getMinParam()) {
// don't suppress bad param exceptions: these need to
// be returned to the user so they know what is wrong
throw new ExFull(new MsgFormat(ResId.BadParamCountException, sFunctionName));
}
for (int i = 0; i < parameters.length; i++) {
//
// ensure we are less than the max num of params.
//
if (i == func.getParamTypes().length) {
// don't suppress bad param exceptions: these need to
// be returned to the user so they know what is wrong
throw new ExFull(new MsgFormat(ResId.BadParamCountException, sFunctionName));
}
//
// ensure the params are correct
//
if (func.getParamTypes()[i] != Arg.INVALID
&& ! parameters[i].isCompatibleWith(func.getParamTypes()[i])) {
//
// don't suppress bad param exceptions: these need to
// be returned to the user so they know what is wrong
//
throw new ExFull(ResId.ArgumentMismatchException);
}
}
//
// params must be ok; check permissions
if (!func.invokePermsFunc(this, parameters)) {
MsgFormatPos message = new MsgFormatPos(ResId.PermissionsViolationExceptionMethod);
message.format(sFunctionName);
throw new ExFull(message);
}
//
// call function
//
func.invoke(scriptThis, retValue, parameters, dependencyTracker);
// ensure the return type is correct
int nRetType = func.getRetType();
//
// JavaPort: TODO. This is new in Java -- this code originally
// asserted, but this isn't programming error; it's a scripting error:
// the function the user called, returned something unexpected (it
// likely threw an exception which got caught and didn't ripple
// through the reflection API). Moreover, this probably needs
// a different ResId.
//
if (nRetType == Arg.INVALID || retValue.isCompatibleWith(nRetType)) {
if (bSuppressExceptions)
return false;
// MsgFormatPos message = new MsgFormatPos(ResId.InvalidMethodException);
// message.format(scriptThis.getClassAtom());
// message.format(sFunctionName);
// retValue.setException(new ExFull(message));
}
}
else if (StringUtils.isEmpty(sFunctionName)) {
if (bSuppressExceptions)
return false;
//
// default method
//
MsgFormatPos message = new MsgFormatPos(ResId.NoDefaultMethodException);
message.format(scriptThis.getClassAtom());
retValue.setException(new ExFull(message));
}
else {
if (bSuppressExceptions)
return false;
MsgFormatPos message = new MsgFormatPos(ResId.InvalidMethodException);
message.format(scriptThis.getClassAtom());
message.format(sFunctionName);
retValue.setException(new ExFull(message));
}
//
// track dependencies if required
//
if (dependencyTracker != null) {
int eType = retValue.getArgType();
if (eType != Arg.EXCEPTION)
dependencyTracker.addDependency(this);
}
return true;
}
/**
* @exclude from published api.
*/
final public boolean isDeaf() {
if (mPeers == null) {
return false;
}
return mPeers.isDeaf();
}
/**
* @exclude from published api.
*/
final public boolean isMute() {
if (mPeers == null) {
return false;
}
return mPeers.isMute();
}
/**
* Determine if the class of this object is the same as the Obj class.
*
* @param oClass
* Obj to check the class with.
* @return true if the classes are the same, else false.
*
* @exclude from published api.
*/
@FindBugsSuppress(code="ES")
public final boolean isSameClass(Obj oClass) {
return oClass.getClassAtom() == getClassAtom();
}
/**
* Determine if the class of this object is the same as the String sClass.
* Note: Works only when comparing to the same actual string instance (from
* the XFA namespace). For example, isSameClass(XFA::nodeTag()) will work if
* the object in question is an Obj. However, isSameClass("node") will not
* work even though the two strings are equal. See the
* SharesImpl
method of String
.
*
* @param aClass
* string from the XFA namespace. This String must be interned.
* @return true if the classes are the same, else false.
*
* @exclude from published api.
*/
@FindBugsSuppress(code="ES")
public final boolean isSameClass(String aClass) {
return aClass == getClassAtom();
}
/**
* Determine if the class of this object is the same as the class tag.
*
* @param eClassTag
* string from the XFA namespace.
* @return true if the classes are the same, else false.
*
* @exclude from published api.
*/
public final boolean isSameClass(int eClassTag) {
return (eClassTag == meClassTag);
}
/**
* @exclude from published api.
*/
final public void mute() {
if (mPeers == null) {
mPeers = new PeerImpl(this);
}
mPeers.mute();
}
/**
* @exclude from published api.
*/
public void notifyPeers(int eventType, String arg1, Object arg2) {
if (mPeers == null) {
return;
}
mPeers.notifyPeers(eventType, arg1, arg2);
}
/**
* Remove a peer node from the notification list.
*
* @param peerNode
* The reference to the peer object to be removed.
*
* @exclude from published api.
*/
final public void removePeer(Peer peerNode) {
if (mPeers == null) {
return;
}
mPeers.removePeer(peerNode);
}
/**
* @exclude from published api.
*/
final public void removePeeredNode(Peer peer) {
if (mPeers == null) {
return;
}
mPeers.removePeeredNode(peer);
}
/**
* Send message to host so it can be logged
* @param error contains message Id and text
* @param eSeverity the message severity
* @exclude from published api.
*/
public void sendMessenge(ExFull error, int eSeverity /* = LogMessage.MSG_WARNING */) {
// Do nothing - derived classes may override
}
/**
* @param sPropertyName
* The name of the property to set. If this parameter is an empty
* string, then an attempt is made to set the default property.
* @param propertyValue
* The value of assign to this property.
* @param bSuppressExceptions
* If true, quietly return false on error, else throw an exception for any errors.
* @exception NoDefaultSetPropertyException
* if sPropertyName is an empty string, and the object does
* not have a default property.
* @exception InvalidSetPropertyException
* if sPropertyName is not a valid property for the object.
*
* @exclude from published api.
*/
public boolean setScriptProperty(String sPropertyName,
Arg propertyValue,
boolean bSuppressExceptions /* = false */) {
// bPropertyOverride(#sPropertyName) means don't hunt for child nodes by name
// only get xfaproperty or child element(based on classname) or script property
boolean bPropertyOverride = sPropertyName.startsWith("#");
String sPropName;
if (bPropertyOverride)
sPropName = sPropertyName.substring(1); // Skip over "#"
else
sPropName = sPropertyName;
boolean bError = false;
Obj scriptThis = getScriptThis();
// bPropertyOverride means don't hunt for child nodes -- only properties are wanted
if (sPropertyName.length() != 0) {
ScriptDynamicPropObj desc = scriptThis.getDynamicScriptProp(sPropName, bPropertyOverride, false);
if (desc != null) {
boolean bReturnVal = false;
// validate that the property exist for this version of the doc, and for this client
if (!validateUsage(desc.getXFAVersion(), desc.getAvailability(), false)) {
final boolean bIsFatal = validateUsageFailedIsFatal(desc.getXFAVersion(), desc.getAvailability());
if (bIsFatal && bSuppressExceptions)
return false;
MsgFormatPos reason = new MsgFormatPos(ResId.InvalidScriptVersionException);
reason.format(getClassAtom());
reason.format(sPropName);
if (bIsFatal)
throw(new ExFull(reason));
else // warn
sendMessenge(new ExFull(reason), LogMessage.MSG_WARNING);
}
if (desc.hasSetter()) {
// check permission
if (!desc.invokePermsFunc(this)) {
MsgFormatPos message = new MsgFormatPos(ResId.PermissionsViolationExceptionProperty);
if (StringUtils.isEmpty(sPropName))
message.format(getClassAtom());
else
message.format(sPropName);
throw new ExFull(message);
}
bReturnVal = desc.invokeSetProp(this, propertyValue, sPropName);
}
if (bReturnVal)
return true;
else if (desc.hasGetter()) {
Arg retVal = new Arg();
boolean bGetProp = desc.invokeGetProp(this, retVal, sPropName);
if (bGetProp && retVal.getArgType() == Arg.OBJECT) {
Obj obj = retVal.getObject();
return obj.setScriptProperty("", propertyValue, bSuppressExceptions);
}
}
// Don't suppress because the user needs to know they are trying to update
// a read property
MsgFormatPos message = new MsgFormatPos(ResId.InvalidSetPropertyException);
message.format(scriptThis.getClassAtom());
message.format(sPropertyName);
throw new ExFull(message);
}
}
if (! bError) {
ScriptPropObj prop = getScriptProp(sPropName);
if (prop != null) {
// validate that the property exists for this version of the doc, and for this client
if (!validateUsage(prop.getXFAVersion(), prop.getAvailability(), false)) {
final boolean bIsFatal = validateUsageFailedIsFatal(prop.getXFAVersion(), prop.getAvailability());
if (bIsFatal && bSuppressExceptions)
return false;
MsgFormatPos reason = new MsgFormatPos(ResId.InvalidScriptVersionException);
reason.format(getClassAtom());
reason.format(sPropertyName);
if (bIsFatal)
throw new ExFull(reason);
else // warn
sendMessenge(new ExFull(reason), LogMessage.MSG_WARNING);
}
if (prop.hasSetter()) {
// ensure the params are correct
if (prop.getParamType() != Arg.INVALID && ! propertyValue.isCompatibleWith(prop.getParamType())) {
// don't suppress bad param exceptions, these need to be returned to the user so they know what
// is wrong
throw new ExFull(ResId.ArgumentMismatchException);
}
// check permissions
if (!prop.invokePermsFunc(this)) {
MsgFormatPos message = new MsgFormatPos(ResId.PermissionsViolationExceptionProperty);
message.format(sPropName);
throw new ExFull(message);
}
//
// The XFAArg::INVALID check guarding the isCompatibileWith() call above exists because
// field value checking is to complicated to run as a pre-flight. Instead, we go ahead
// and do the set, letting the set code generate any errors, and then fish the errors
// out and throw them.
// (In particular, XFAFloatImpl's, XFADecimalImpl's and XFAIntegerImpl's setValue() calls
// are all known to generate type mismatch error entries.)
//
Model oModel = null;
LogMessenger oTempLogMessenger = new LogMessenger();
LogMessenger oSaveLogMessenger = null;
int nStartErrorCount = 0;
if (this instanceof Element) {
oModel = ((Element)this).getModel();
}
if (oModel != null) {
// plug in a temp LogMessenger so that any error messages generated
// don't get sent to a log file
oSaveLogMessenger = oModel.getLogMessenger();
oModel.setLogMessenger(oTempLogMessenger);
nStartErrorCount = oModel.getErrorList().size();
}
bError = prop.invokeSetProp(this, propertyValue);
if (oModel != null) {
// restore the LogMessenger (the old one must be cleared first
// as setLogMessenger() will copy any pending messages from it to
// the new one)
oTempLogMessenger.removeStoredMessages();
oModel.setLogMessenger(oSaveLogMessenger);
// and now check to see if there are any additional messages in
// the errorList which we want to extract and throw back to our
// script
if (oModel.getErrorList().size() > nStartErrorCount) {
int nErrors = oModel.getErrorList().size();
ExFull oError = oModel.getErrorList().get(nErrors - 1);
oModel.removeLastError();
MsgFormatPos sError = new MsgFormatPos(oError.toString());
throw new ExFull(sError);
}
}
if (! bError)
return true;
}
// Don't suppress because the user needs to know they are trying to update
// a read property
MsgFormatPos message = new MsgFormatPos(ResId.InvalidSetPropertyException);
message.format(scriptThis.getClassAtom());
message.format(sPropertyName);
throw new ExFull(message);
}
else if (sPropName.length() == 0) {
if (bSuppressExceptions)
return false;
// default property
MsgFormatPos message = new MsgFormatPos(ResId.NoDefaultSetPropertyException, getClassAtom());
throw new ExFull(message);
}
else { // unknown property
if (bSuppressExceptions)
return false;
MsgFormatPos message = new MsgFormatPos(ResId.InvalidSetPropertyException);
message.format(scriptThis.getClassAtom());
message.format(sPropertyName);
throw new ExFull(message);
}
}
return true;
}
/**
* @exclude from published api.
*/
final public void unDeafen() {
if (mPeers == null) {
return;
}
mPeers.unDeafen();
}
/**
* @exclude from published api.
*/
final public void unMute() {
if (mPeers == null) {
return;
}
mPeers.unMute();
}
/**
* @exclude from published api.
*/
public void updateFromPeer(Object peerNode, int eventType, String arg1, Object arg2) {
// Do nothing
// Derived classes can override this to receive peer update notifications
}
/**
* @exclude from public api.
*/
public void peerRemoved(Peer peer) {
// Do nothing
// Derived classes can override this to receive peerRemoved notifications
}
/**
* Validate if the given Version and Availability flags are valid for the
* current document
*
* @param nXFAVersion
* The target XFA Version
* @param nAvailability
* The target Availability flags, this indicates for what clients
* the script is available
* @param bUpdateVersion
* indicates if the model version can be updated by the calling
* code
* @return if true, Version and Availability flags are valid
*
* @exclude from published api.
*/
public boolean validateUsage(int nXFAVersion, int nAvailability, boolean bUpdateVersion) {
return true;
}
/**
* Determines if disallowing a version should be considered a fatal error.
*
* This method is called after calling
* {@link #validateUsage(int, int, boolean)} when that method returns false.
*
* @param nXFAVersion
* The target XFA Version
* @param nAvailability
* The target Availability flags, this indicates for what clients
* the script is available
* @return true if disallowing nVersion should be considered a fatal error
*
* @see #validateUsage(int, int, boolean)
* @exclude from published api.
*/
public boolean validateUsageFailedIsFatal(int nXFAVersion, int nAvailability) {
return false;
}
}