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

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

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 java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.UnsupportedEncodingException;

import com.adobe.xfa.Element.ReplaceContent;
import com.adobe.xfa.content.ExDataValue;
import com.adobe.xfa.template.containers.Variables;
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.ResId;
import com.adobe.xfa.ut.StringUtils;


/**
 * This class contains all the script functionality associated with the
 * Element class.  Broken out into a separate class for easier maintainability.
 *
 * @exclude from published api.
 */
public class ElementScript extends NodeScript {

	protected static final ScriptTable moScriptTable = new ScriptTable(
		NodeScript.moScriptTable,
		"element",
		new ScriptPropObj[] {
			new ScriptPropObj(ElementScript.class, "isNull", "getIsNull", null, Arg.BOOL, Schema.XFAVERSION_10, Schema.XFAAVAILABILITY_CORE | Schema.XFAAVAILABILITY_PLUGIN/*, XFA_IS_ISNULL_DESC, XFA_IS_ISNULL_RET*/, 0),
			new ScriptPropObj(ElementScript.class, "oneOfChild", "getOneOfChild", "setOneOfChild", Arg.OBJECT, Schema.XFAVERSION_10, Schema.XFAAVAILABILITY_CORE | Schema.XFAAVAILABILITY_PLUGIN/*, XFA_IS_ONEOFCHILD, 0*/, 0),
			new ScriptPropObj(ElementScript.class, "id", "getId", "setId", Arg.STRING, Schema.XFAVERSION_10, Schema.XFAAVAILABILITY_CORE | Schema.XFAAVAILABILITY_PLUGIN/*, XFA_IS_ID, 0*/, 0),
			new ScriptPropObj(ElementScript.class, "ns", "getNs", null, Arg.STRING, Schema.XFAVERSION_10, Schema.XFAAVAILABILITY_CORE | Schema.XFAAVAILABILITY_PLUGIN/*, XFA_IS_GETNS, 0*/, 0)
		},
		new ScriptFuncObj[] {
			new ScriptFuncObj(ElementScript.class, "clone", "clone", Arg.OBJECT,
					new int[] { Arg.BOOL/*, XFA_IS_CLONE_PARAM */ }, 1, Schema.XFAVERSION_10, Schema.XFAAVAILABILITY_CORE | Schema.XFAAVAILABILITY_PLUGIN/*, XFA_IS_CLONE_DESC, XFA_IS_CLONE_RET*/, 0),
			new ScriptFuncObj(ElementScript.class, "isPropertySpecified", "isPropertySpecified", Arg.BOOL,
					new int[] { Arg.STRING, Arg.BOOL, Arg.INTEGER/*, XFA_IS_ISPROPERTYSPECIFIED_PARAM1, XFA_IS_ISPROPERTYSPECIFIED_PARAM2, XFA_IS_ISPROPERTYSPECIFIED_PARAM3*/ }, 1, Schema.XFAVERSION_10, Schema.XFAAVAILABILITY_CORE | Schema.XFAAVAILABILITY_PLUGIN/*, XFA_IS_ISPROPERTYSPECIFIED_DESC, XFA_IS_ISPROPERTYSPECIFIED_RET*/, 0),
			new ScriptFuncObj(ElementScript.class, "getElement", "getElement", Arg.OBJECT,
					new int[] { Arg.STRING, Arg.INTEGER/*, XFA_IS_GETELEMENT_PARAM1, XFA_IS_GETELEMENT_PARAM2 */}, 1, Schema.XFAVERSION_10, Schema.XFAAVAILABILITY_CORE | Schema.XFAAVAILABILITY_PLUGIN/*, XFA_IS_GETELEMENT_DESC, XFA_IS_GETELEMENT_RET*/, 0),
			new ScriptFuncObj(ElementScript.class, "setElement", "setElement", Arg.EMPTY,
					new int[] { Arg.OBJECT, Arg.STRING/*, XFA_IS_SETELEMENT_PARAM1, XFA_IS_SETELEMENT_PARAM2 */}, 1, Schema.XFAVERSION_10, Schema.XFAAVAILABILITY_CORE | Schema.XFAAVAILABILITY_PLUGIN/*, XFA_IS_SETELEMENT_DESC, 0*/, "setElementPermsCheck", 0),
			new ScriptFuncObj(ElementScript.class, "getAttribute", "getAttribute", Arg.STRING,
					new int[] { Arg.STRING /*, XFA_IS_GETATTRIBUTE_PARAM1 */}, 1, Schema.XFAVERSION_10, Schema.XFAAVAILABILITY_CORE | Schema.XFAAVAILABILITY_PLUGIN/*, XFA_IS_GETATTRIBUTE_DESC, XFA_IS_GETATTRIBUTE_RET*/, 0),
			new ScriptFuncObj(ElementScript.class, "setAttribute", "setAttribute", Arg.EMPTY,
					new int[] { Arg.STRING, Arg.STRING/*, XFA_IS_SETATTRIBUTE_PARAM1, XFA_IS_SETATTRIBUTE_PARAM2 */}, 2, Schema.XFAVERSION_10, Schema.XFAAVAILABILITY_CORE | Schema.XFAAVAILABILITY_PLUGIN/*, XFA_IS_SETATTRIBUTE_DESC, 0*/, "setAttributePermsCheck", 0),
			new ScriptFuncObj(ElementScript.class, "loadXML", "loadXML", Arg.EMPTY,
					new int[] { Arg.STRING, Arg.BOOL, Arg.BOOL /*, XFA_IS_LOADXML_PARAM1, XFA_IS_LOADXML_PARAM2, XFA_IS_LOADXML_PARAM3*/ }, 1, Schema.XFAVERSION_10, Schema.XFAAVAILABILITY_CORE | Schema.XFAAVAILABILITY_PLUGIN/*, XFA_IS_LOADXML_DESC, 0*/, "loadXMLPermsCheck", 0),
			new ScriptFuncObj(ElementScript.class, "saveXML", "saveXML", Arg.STRING,
					new int[] { Arg.STRING /*, XFA_IS_SAVEXML_PARAM1*/ }, 0, Schema.XFAVERSION_10, Schema.XFAAVAILABILITY_CORE | Schema.XFAAVAILABILITY_PLUGIN/*, XFA_IS_SAVEXML_DESC, XFA_IS_SAVEXML_RET*/, 0),
			new ScriptFuncObj(ElementScript.class, "saveFilteredXML", "saveFilteredXML", Arg.STRING, 
					new int[] { Arg.OBJECT, Arg.STRING /*, XFA_IS_SAVEFILTEREDXML_PARAM1, XFA_IS_SAVEFILTEREDXML_PARAM2*/ }, 1, Schema.XFAVERSION_24, Schema.XFAAVAILABILITY_CORE|Schema.XFAAVAILABILITY_PLUGIN/*, XFA_IS_SAVEFILTEREDXML_DESC, XFA_IS_SAVEFILTEREDXML_RET, null*/, 0),
			new ScriptFuncObj(ElementScript.class, "applyXSL", "applyXSL", Arg.STRING,
					new int[] { Arg.STRING /*, XFA_IS_APPLYXSL_PARAM*/ }, 1, Schema.XFAVERSION_10, Schema.XFAAVAILABILITY_CORE | Schema.XFAAVAILABILITY_PLUGIN/*, XFA_IS_APPLYXSL_DESC, XFA_IS_APPLYXSL_RET*/, 0),
			new ScriptFuncObj(ElementScript.class, "assignNode", "assignNode", Arg.OBJECT,
					new int[] { Arg.STRING, Arg.STRING, Arg.INTEGER /*, XFA_IS_ASSIGNNODE_PARAM1, XFA_IS_ASSIGNNODE_PARAM2, XFA_IS_ASSIGNNODE_PARAM3*/ }, 1, Schema.XFAVERSION_10, Schema.XFAAVAILABILITY_CORE | Schema.XFAAVAILABILITY_PLUGIN/*, XFA_IS_ASSIGNNODE_DESC, XFA_IS_ASSIGNNODE_RET*/, "assignNodePermsCheck", 0),
			new ScriptFuncObj(ElementScript.class, "resolveNode", "resolveNode", Arg.OBJECT,
					new int[] { Arg.STRING /*, XFA_IS_RESOLVENODE_PARAM */ }, 1, Schema.XFAVERSION_10,  Schema.XFAAVAILABILITY_ALL/*, XFA_IS_RESOLVENODE_DESC, XFA_IS_RESOLVENODE_RET, null*/, 0),
			new ScriptFuncObj(ElementScript.class, "resolveNodes", "resolveNodes", Arg.OBJECT,
					new int[] { Arg.STRING /*, XFA_IS_RESOLVENODES_PARAM */ }, 1, Schema.XFAVERSION_10, Schema.XFAAVAILABILITY_ALL/*, XFA_IS_RESOLVENODE_DESC, XFA_IS_RESOLVENODES_RET, null*/, 0)
		}
	);
	
	public static ScriptTable getScriptTable() {
		return moScriptTable;
	}	
	
	// ------------------------------------------------------------------------
	// Script Properties
	
	public static void getIsNull(Obj obj, Arg retVal) {
		if (obj instanceof Element)
    		retVal.setBool(Boolean.valueOf(((Element) obj).getIsNull()));
		else if (obj instanceof TextNode)
    		retVal.setBool(Boolean.FALSE);
	}
	
	public static void getOneOfChild(Obj obj, Arg retVal) {
		if (obj instanceof Element)
    		retVal.setObject(((Element) obj).getOneOfChild());
		else
			retVal.setObject(null);
	}
	
	public static void setOneOfChild(Obj obj, Arg oArg) {
		// check object type
		Obj child = oArg.getObject();
		if (!(child instanceof Node))
			throw new ExFull(ResId.ArgumentMismatchException);
		
		if (obj instanceof Element)
    		((Element) obj).setOneOfChild((Node) child);
		else {
			MsgFormatPos message = new MsgFormatPos(ResId.InvalidSetOneOfException);
			message.format(child.getClassAtom());
			throw new ExFull(message);
		}
	}
	
	public static void getId(Obj obj, Arg retVal) {
		if (obj instanceof Element)
    		retVal.setString(((Element) obj).getID());
		else
    		retVal.setString("");
	}
	
	public static void setId(Obj obj, Arg oArg) {
		if (obj instanceof Element)
    		((Element) obj).setID(oArg.getString());
		else {
			MsgFormatPos message = new MsgFormatPos(ResId.InvalidSetPropertyException);
			message.format(obj.getClassAtom());
			message.format(XFA.ID);
			throw new ExFull(message);
		}
	}
	
	public static void getNs(Obj obj, Arg retVal) {
		if (obj instanceof Element)
    		retVal.setString(((Element) obj).getNSInternal());
		else if (obj instanceof TextNode)
    		retVal.setString("");
	}
	
	
	// ------------------------------------------------------------------------
	// Script Functions
	
	public static void clone(Obj obj, Arg retVal, Arg[] args) {
		boolean bRecursive = args[0].getBool().booleanValue();
		
		if (obj instanceof Element)			
			retVal.setObject(((Element) obj).clone(null, bRecursive));
		else
			retVal.setObject(((Node)obj).clone(null));
	}
	
	public static void isPropertySpecified(Obj obj, Arg retVal, Arg[] args) {
		if (obj instanceof Element) {
			Element e = (Element) obj;
			String propertyName = args[0].getString();
			boolean bCheckProtos = args.length < 2 ? true : args[1].getBool().booleanValue();
			int occurrence = args.length < 3 ? 0 : args[2].getInteger().intValue();
			retVal.setBool(Boolean.valueOf(e.isPropertySpecified(propertyName, bCheckProtos, occurrence)));
		}
		else {
	    	retVal.setBool(Boolean.FALSE);
		}
	}
	
	public static void getElement(Obj obj, Arg retVal, Arg[] args) {
		
		if (!(obj instanceof Element))	// TextNode?
			return;
		Element e = (Element) obj;
		
		String propName = args[0].getString().intern();
		int occurrence = args.length == 1 ? 0 : args[1].getInteger().intValue();

		Object property = e.getProperty(propName, occurrence);			
		if (property == null)
			return;
		else if (!(property instanceof Element))
			throw new ExFull(new MsgFormat(ResId.InvalidAttributeException, " element[" + propName + STRS.RIGHTBRACE));
		else
			retVal.setObject((Element)property);
	}
	
	public static void setElement(Obj obj, Arg retVal, Arg[] args) {
		
		Obj property = args[0].getObject();		
		if (!(property instanceof Element))
			throw new ExFull(ResId.ArgumentMismatchException);
		
		String propertyName = args.length < 2 ? "" : args[1].getString();
		
		if (obj instanceof Element)		
			((Element)obj).setProperty(property, propertyName);
		else {
			MsgFormatPos message = new MsgFormatPos(ResId.InvalidSetPropertyException);
			message.format(obj.getClassAtom());
			message.format(propertyName);
			throw new ExFull(message);
		}
	}

	public static void getAttribute(Obj obj, Arg retVal, Arg[] args) {
		
		if (!(obj instanceof Element))	// TextNode?
			return;
		
		String propName = args[0].getString();
		
		Object property = ((Element)obj).getProperty(propName, 0);		
		if (property == null)
			return;
		else if (!(property instanceof Attribute))
			 throw new ExFull(ResId.InvalidAttributeException, " attribute[" + propName + STRS.RIGHTBRACE);
		else
			retVal.setString(property.toString());
	}

	public static void setAttribute(Obj obj, Arg retVal, Arg[] args) {
		String aAttrName = args[1].getString(); // may be null
		if (aAttrName != null)
			aAttrName = aAttrName.intern();

		int eTag = -1;
		if (aAttrName != null)
			eTag = XFA.getTag(aAttrName);
		
		if (obj instanceof Element && eTag != -1) {
			((Element) obj).setAttribute(((Element) obj).newAttribute(eTag, args[0].getString()), eTag);
		} else {
			MsgFormatPos oMessage = new MsgFormatPos(ResId.InvalidSetPropertyException);
			oMessage.format(((Node) obj).getClassAtom());
			oMessage.format(aAttrName);
			throw new ExFull(oMessage);
		}
	}
	
	public static void loadXML(Obj obj, Arg retVal, Arg[] args) {
		
		if (!(obj instanceof Element)) {
			// Anything other than an element (i.e., TextNode) is not a valid parent
			MsgFormatPos message = new MsgFormatPos(ResId.ParentChildViolationException);			
			throw new ExFull(message);
		}
		
        try {
        	ByteArrayInputStream streamFile;
            streamFile = new ByteArrayInputStream(args[0].getString().getBytes(Document.Encoding));
    		boolean bIgnoreAggregatingTag = true;
    		boolean bReplaceContent = false;
    		if (args.length == 1) {
    			// watson bug 1328860
    			// Ugly but we need to respect the default value for bIgnoreAggregatingTag on exData nodes.
    			if (obj instanceof ExDataValue) {
    				bIgnoreAggregatingTag = false;
    			}
    		}
    		
    		if (args.length >= 2)
    			bIgnoreAggregatingTag = args[1].getBool().booleanValue();
    		
    		if (args.length == 3)
    			bReplaceContent = args[2].getBool().booleanValue();
    
    		// loadXML takes a three way enum to control replacing nothing, XFA content only or XFA and DOM content.
    		// Need to map existing script interface (bool bReplaceContent) to this enum. Legacy behavior replaces
    		// XFA content only and leaves additional DOM content untouched.  
    		// (Ref Watson 1931282 which require full replace for XFA and DOM content during undo)
    		
    		ReplaceContent eReplace = ReplaceContent.None;
    		
    		if (bReplaceContent){
    			// Watson 2378040: loadXML() need to replace DOM content as well if this is an XFAPacket (but only if v3.3 or higher)
    			if ( obj instanceof Packet && ((Packet)obj).getAppModel().getLegacySetting(AppModel.XFA_LEGACY_V32_SCRIPTING))
    				eReplace = ReplaceContent.AllContent;
    			else
    				eReplace = ReplaceContent.XFAContent;
    		}
    		((Element)obj).loadXML(streamFile, bIgnoreAggregatingTag, eReplace);
        } catch (UnsupportedEncodingException e) {
        }
	}

	public static void saveXML(Obj obj, Arg retVal, Arg[] args, DependencyTracker dependencyTracker) {
		
		// Form dependency with child nodes
		addDependency((Element)obj, dependencyTracker);
		
		//Bug fix for watson bug 1684847.   
		// saveXML shouldn't save out transient nodes by default
		DOMSaveOptions options = new DOMSaveOptions();
		options.setSaveTransient(((Element)obj).getSaveXMLSaveTransient());	// Watson 1778700: Content-derived classes should save transient nodes in saveXML.
		
		ByteArrayOutputStream memStream = new ByteArrayOutputStream();
		if (args.length == 1) {
			if (args[0].getString().equals("pretty")) {
				options.setDisplayFormat(DOMSaveOptions.PRETTY_OUTPUT);
			}
			else {
				MsgFormatPos message = new MsgFormatPos(ResId.ArgumentMismatchException);
				throw new ExFull(message);
			}
		}
		
		if (obj instanceof Element)
			((Element) obj).saveXML(memStream, options, true);
		else if (obj instanceof Node) {
			Node node = (Node)obj;
			// JavaPort: It is unlikely that we would save a TextNode, but
			// do it for consistency with C++.			
			node.getOwnerDocument().saveAs(memStream, node, options);
		}			

		String result = "";
		try {
			result = memStream.toString("UTF-8");			
		}
		catch (UnsupportedEncodingException ex) {
			// Not possible - UTF-8 is always supported
		}
		
		// JavaPort: The C++ implementation of jfMemoryStreamFile::toString() will truncate any trailing newline
		if (result.endsWith("\n"))
			result = result.substring(0, result.length() - 1);
		
		retVal.setString(result);
	}
	
	public static void saveFilteredXML(Obj obj, Arg retVal, Arg[] args, DependencyTracker dependencyTracker) {
		// First check that the first argument is indeed a NodeList.
		Obj object = args[0].getObject();
		if (! (object instanceof NodeList))
			throw new ExFull(ResId.ArgumentMismatchException);
		
		ByteArrayOutputStream memStreamFile = new ByteArrayOutputStream();
		addDependency(((Element) obj), dependencyTracker);
		//
		// Bug fix for watson bug 1684847.   
		// saveXML shouldn't save out transient nodes by default
		//
		DOMSaveOptions options = new DOMSaveOptions();
		options.setSaveTransient(false);
		if (args.length == 2) {
			if (args[1].getString().equals("pretty")) {
				options.setSaveTransient(true);
				options.setDisplayFormat(DOMSaveOptions.PRETTY_OUTPUT);
			} 
			else {
				MsgFormatPos oMessage = new MsgFormatPos(ResId.ArgumentMismatchException);
				throw new ExFull(oMessage);
			}
		}
		
		if (obj instanceof Element)
			((Element) obj).saveFilteredXML((NodeList) object, memStreamFile, options);
		else if (obj instanceof Node){
			Node node = (Node)obj;
			// JavaPort: It is unlikely that we would save a TextNode, but
			// do it for consistency with C++.			
			node.getOwnerDocument().saveAs(memStreamFile, node, options);
		}
		
		try {
			retVal.setString(memStreamFile.toString("UTF-8"));
		}
		catch (UnsupportedEncodingException ex) {
			// Not possible - UTF-8 is always supported
		}
	}
	
	public static void applyXSL(Obj obj, Arg retVal, Arg[] args) {
		
		// Since this method is equivalent to serializing as XML and then
		// applying a transformation to the stream, it is not valid if applied
		// to anything other than an Element since the XML infoset would not
		// be valid.
		
		if (!(obj instanceof Element)) {
			MsgFormatPos message = new MsgFormatPos(ResId.InvalidMethodException);
			message.format(obj.getClassAtom());
			message.format("applyXSL");
			throw new ExFull(message);
		}
		
		ByteArrayInputStream xslTransformStream;
        try {
            xslTransformStream = new ByteArrayInputStream(args[0].getString().getBytes(Document.Encoding));
    		ByteArrayOutputStream resultStream = new ByteArrayOutputStream();
    		((Element) obj).applyXSL(xslTransformStream, resultStream);
			retVal.setString(resultStream.toString("UTF-8"));
		}
		catch (UnsupportedEncodingException ex) {
			// Not possible - UTF-8 is always supported
		}
	}
	
	/**
	 * Static method for invoking functions in the script interface
	 */
	public static void assignNode(Obj obj, Arg retVal, Arg[] args) {
		
		// JavaPort: It is conceivable that this could have been called on a text node
		// in the C++ implementation, but it doesn't seem likely.
		if (!(obj instanceof Element)) {
			MsgFormatPos message = new MsgFormatPos(ResId.InvalidMethodException);
			message.format(obj.getClassAtom());
			message.format("assignNode");
			throw new ExFull(message);
		}
		
		retVal.setObject(((Element) obj).assignNode(args[0].getString(), args[1].getString(), args[2].getInteger().intValue()));
	}

	public static void resolveNode(Obj obj, Arg retVal, Arg[] args, DependencyTracker dependencyTracker) {
		// only new docs should use the dependency tracker
		AppModel oAppModel = ((Element) obj).getAppModel();
		DependencyTracker oDependencyTracker = null;
		// watson bug 1917077 for new documents ensure we track dependancies on naked field references.
		if (oAppModel != null && ! oAppModel.getLegacySetting(AppModel.XFA_LEGACY_V29_SCRIPTING))
			oDependencyTracker = dependencyTracker;
		retVal.setObject(((Element) obj).resolveNode(args[0].getString(), false, false, false, oDependencyTracker, null));
	}

	public static void resolveNodes(Obj obj, Arg retVal, Arg[] args, int nParamCount, DependencyTracker dependencyTracker) {
		// only new docs should use the dependency tracker
		AppModel oAppModel = ((Element) obj).getAppModel();
		DependencyTracker oDependencyTracker = null;
		// watson bug 1917077 for new documents ensure we track dependancies on naked field references.
		if (oAppModel != null && ! oAppModel.getLegacySetting(AppModel.XFA_LEGACY_V29_SCRIPTING))
			oDependencyTracker = dependencyTracker;
		retVal.setObject(((Element) obj).resolveNodes(args[0].getString(), false, false, false, oDependencyTracker, null));
	}
	
	// ------------------------------------------------------------------------
	// Methods invoked through reflection to support getDynamicScriptProp
	

	// func to get a oneOfChild. used by Element.getDynamicScriptProp
	public static boolean locateOneOf(Obj obj, Arg retVal, String sProp) {
		if (StringUtils.isEmpty(sProp))
			return false;

		int nTag = XFA.getTag(sProp);
		if (nTag == -1)
			return false;

		int eTag = nTag;

		int eType = ((Element) obj).getSchemaType(eTag);

		if (eType == Element.ONEOF) {
			Node pOneOf = ((Element) obj).getOneOfChild(true, false);
			if (pOneOf != null && pOneOf.getClassTag() == eTag) {
				pOneOf = ((Element) obj).getOneOfChild(false, false);
				retVal.setObject(pOneOf);
				return true;
			}
		}
		return false;
	}

	// func to get a property. used by Element.getDynamicScriptProp
	public static boolean locateProp(Obj obj, Arg retVal, String sProp) {
		if (StringUtils.isEmpty(sProp))
			return false;

		int nTag = XFA.getTag(sProp);
		if (nTag == -1)
			return false;
		int eTag = nTag;

		int eType = ((Element) obj).getSchemaType(eTag);

		if (eType != Element.ATTRIBUTE /* && eType != Element.TEXT */ && eType != Element.ELEMENT)
			return false;

		Element oNode = (Element) obj;

		if (eType == Element.ATTRIBUTE) {
			Attribute oProp = oNode.getAttribute(eTag, false, false);
			if (oProp != null) {
				retVal.setString(oProp.toString());
				return true;
			}
		} else {
			Element oProp = oNode.getElement(eTag, 0);
			if (oProp != null) {
				retVal.setObject(oProp);
				return true;
			}
		}
		return false;
	}

	// func to get a property. used by Element.getDynamicScriptProp
	public static boolean locatePropPeek(Obj obj, Arg retVal, String sProp) {
		if (StringUtils.isEmpty(sProp))
			return false;

		int nTag = XFA.getTag(sProp);
		if (nTag == -1)
			return false;
		int eTag = nTag;

		int eType = ((Element) obj).getSchemaType(eTag);

		if (eType != Element.ATTRIBUTE /* && eType != Element.TEXT */ && eType != Element.ELEMENT)
			return false;

		if (eType == Element.ATTRIBUTE) {
			Attribute prop = ((Element) obj).getAttribute(eTag, true, false);
			if (prop != null) {
				retVal.setString(prop.toString());
				return true;
			}
		} else {
			Element prop = ((Element) obj).getElement(eTag, true, 0, false,
					false);
			if (prop != null) {
				retVal.setObject(prop);
				return true;
			}
		}

		return false;
	}

	// See Element.getDynamicScriptProp
	@FindBugsSuppress(code="ES")
	public static boolean setProp(Obj obj, Arg arg, String sProp) {
		if (StringUtils.isEmpty(sProp))
			return false;

		int eTag = XFA.getTag(sProp);
		if (eTag == -1)
			return false;
		
		if (!(obj instanceof Element))
			return false;
		
		Element elementThis = (Element)obj;

		int eType = elementThis.getSchemaType(eTag);

		if (eType != Element.ATTRIBUTE)
			return false;

		StringAttr prop = new StringAttr(sProp, arg.getString());
		elementThis.setAttribute(prop, eTag);
		return true;
	}
	

	// ------------------------------------------------------------------------
	// Utilities used elsewhere within this package	

	// JavaPort: This is incompletely implemented in XFA4J, and is only used by Designer.
//	// Search for a named child, handling transparent nodes.
//	// helper function
//	// Used by Element.getDynamicScriptProps
//	static void getScriptChildList(Element e, List oChildList) {
//
//		Node child = e.getFirstXFAChild();
//		while (child != null) {
//			int eType = e.getSchemaType(child.getClassTag());
//
//			if (eType == Element.CHILD || eType == Element.ONEOF) {
//				String sName = child.getSomName();
//
//				if (sName.length() > 0)
//					oChildList.add(sName);
//
//				// if the child is transparent, treat its children as if they
//				// were at the same level as the child.
//				if (child instanceof Element && child.isTransparent())
//					getScriptChildList((Element)child, oChildList);
//			}
//			child = child.getNextXFASibling();
//		}
//	}

	
	// ------------------------------------------------------------------------
	// Utilities used by other script functions
	
	private static void addDependency(Node node, DependencyTracker dependencyTracker) {
		if (dependencyTracker != null && node != null && !(node instanceof Variables)) {
			dependencyTracker.addDependency(node);   
	 
			for (Node child = node.getFirstXFAChild(); child != null; child = child.getNextXFASibling())
				addDependency(child, dependencyTracker);		
		}
	}


	// ------------------------------------------------------------------------
	// Script Permission Check Functions

	public static boolean setElementPermsCheck(Obj obj, Arg[] args) {
		//	Check permissions on the parent node and all its ancestors.
		//	Check permissions on the node to replace and all its decendents.
		
		if (obj instanceof Element) {
			Element element = (Element)obj;
			
			// check perms on the parent
			if (!element.checkAncestorPerms())
				return false;

			// extract the new child
			Obj object = args[0].getObject();
			if (!(object instanceof Node))
				throw new ExFull(ResId.ArgumentMismatchException);
			
			Node node = (Node)object;
			
			// check if the new element already exists
			Element oldChild = element.getElement(node.getClassTag(), 0);
			if (oldChild != null) {	
				// check perms on the old child
				if (!oldChild.checkDescendentPerms())
					return false;
			}
		}

		return true;
	}

	public static boolean setAttributePermsCheck(Obj obj, Arg[] args) {
		//	Check permissions on the parent node and all its ancestors.
		//	Check permissions on the attribute to replace.
		
		if (obj instanceof Element) {
			Element element = (Element)obj;
			
			// check perms on the parent
			if (! element.checkAncestorPerms())
				return false;

			// Javaport: The following section doesn't make sense in XFA4J
			// since the the XFA DOM object that represents the attribute
			// will never be derived from XFATreeImpl, and therefore cannot
			// be locked. However, MDP/MDP+ never applies a permissions lock
			// at the attribute level, so this is not an issue.

//			// extract the new attribute
//			String aAttrName = args[1].getString();
//
//			// check if the new element already exists
//			jfDomNode oAttr = self(obj)->getAttributeNode(aAttrName);
//			if (! oAttr.isNull())
//			{
//				jfObjImpl* poUserObject = oAttr.getImpl().getUserObject();
//				if (poUserObject && poUserObject->IsDerivedFrom(JF_CLS_XFATREE))
//				{
//					// check perms on the old attribute
//					XFATreeImpl* poAttr = (XFATreeImpl*)poUserObject;
//
//					if (! poAttr->checkPerms())
//						return false;
//				}
//			}
		}

		return true;
	}

	public static boolean loadXMLPermsCheck(Obj obj, Arg[] args) {
		//	Check permissions on the parent node and all its ancestors.
		//	if replace operation is selected
		//		Check permissions on all the descendent nodes.
		
		if (obj instanceof Element) {	
			Element element = (Element)obj;
			
			// check perms on the parent
			if (! element.checkAncestorPerms())
				return false;

			if (args.length == 3) {
				// if we are doing a replace, we must check perms on all children too
				boolean bReplace = args[2].getBool().booleanValue();
				if (bReplace) {
					if (!element.checkDescendentPerms())
						return false;
				}
			}
		}

		return true;
	}

	public static boolean assignNodePermsCheck(Obj obj, Arg[] args) {
		//	if replace is selected
		//		Check permissions on resolved node and all its ancestors.
		//		Check permissions on resolved node and all its descendents.
		//	otherwise
		//		Check permissions on new node's parent and all its ancestors.
		
		if (obj instanceof Element && args.length >= 1) {
			Element element = (Element)obj;
			
			Node resolvedNode = element.resolveNode(args[0].getString(), true, false, false);
			if (resolvedNode != null) {
				// node already exists
				if (args.length < 3 || args[2].getInteger().intValue() == 0) {
					// check perms on the resolved node and all its ancestors
					if (! resolvedNode.checkAncestorPerms())
						return false;

					// check perms on the resolved node and all its descendents
					if (! resolvedNode.checkDescendentPerms())
						return false;
				}
			}
			else if (args[2].getInteger().intValue() != 0) {
				// find the parent and check perms on it and all its ancestors
				String sCopy = args[0].getString();
				if (sCopy.length() != 0) {
					Node parent = element.resolveNode(sCopy, true, false, false);
					while (parent == null && sCopy.length() != 0) {	
						boolean bTrimmed = false;

						int nFoundAt;
						int nOffset = 0;
						while ((nFoundAt = sCopy.indexOf('.', nOffset)) != -1) {
							bTrimmed = true;
							nOffset = nFoundAt + 1;
						}

						if (bTrimmed)
							sCopy = sCopy.substring(0, nOffset - 1);
						else
							break;

						parent = element.resolveNode(sCopy, true, false, false);
					}

					if (parent instanceof Node) {
						Node parentNode = parent;
						if (!parentNode.checkAncestorPerms())
							return false;
					}
				}
			}
		}

		return true;
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy