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

com.adobe.xfa.content.Content 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.content;

import org.xml.sax.Attributes;

import com.adobe.xfa.Attribute;
import com.adobe.xfa.Element;
import com.adobe.xfa.Node;
import com.adobe.xfa.ProtoableNode;
import com.adobe.xfa.STRS;
import com.adobe.xfa.XFA;
import com.adobe.xfa.ScriptTable;
import com.adobe.xfa.TextNode;
import com.adobe.xfa.ut.StringUtils;


/**
 * Base class for all the XFA types that hold content (integer, text, image etc)
 *
 * @exclude from published api.
 */
public class Content extends ProtoableNode {

	boolean mbIsNull;

	boolean mbIsNullDetermined;

	protected Content() {

	}

	protected Content(Element parent, Node prevSibling, String uri,
			String localName, String qName, Attributes attributes,
			int classTag, String className) {
		super(parent, prevSibling, uri, localName, qName, attributes, classTag,
				className);
		
		setSaveXMLSaveTransient(true);	// Watson 1778700: XFAContentImpl-derived classes should save transient nodes in saveXML.
	}

	public void appendChild(Node poChild, boolean bValidate) {
		super.appendChild(poChild, bValidate);
		if (mbIsNullDetermined) {
			mbIsNullDetermined = false; // reset null
			removeXsiNilAttribute();
		}
	}

	protected void childRemoved(Node poChild) {
		super.childRemoved(poChild);
		if (mbIsNullDetermined) {
			mbIsNullDetermined = false; // reset null
			removeXsiNilAttribute();
		}
	}

	// for xfaformfield
	public boolean couldBeNull() {

		if (getIsNull())
			return true;

		Attribute attr = getXsiNilAttribute();

		// JavaPort: this looks like a bug - it could have either value!
		// xsi:nil must be set to false
		if (attr != null)
			return false;

		// has a string value so can't be null
		if (!StringUtils.isEmpty(getStrValue()))
			return false;

		// could be null
		return true;
	}

	/**
	 * Equals is a helper function that returns whether two Contents are equal
	 * (case-sensitive, and considering the null state of both
	 * nodes).
	 * 
	 * @param object
	 *            the content node to compare.
	 * @return true if the content nodes are equal.
	 */
	public boolean equals(Object object) {
		
		if (this == object)
			return true;
		
		// This method overrides Object.equals(boolean), so...
		if (object == null) 
			return false;
		
		if (object.getClass() != getClass()) 
			return false;			
		
		// TODO: Can the class tags ever be different if they are the same Java class?
		Content content = (Content) object;
		if (!isSameClass(content.getClassTag()))
			return false;
		
		return getIsNull() == content.getIsNull();
	}
	
	/**
	 * Returns a hash code value for the object. This method is unsupported.
	 * @exclude from published api.
	 */
	public int hashCode() {
		return getIsNull() ? 0 : 31;
	}

	public boolean getIsNull() {
		if (!mbIsNullDetermined) {

			mbIsNullDetermined = true;
			mbIsNull = false;

			Attribute attr = getXsiNilAttribute();

			// check the xsi:nil attr
			if (attr != null)
				mbIsNull = attr.getAttrValue().equals(STRS.TRUE);
			else if (getFirstXFAChild() == null) { // has no children
				// check proto
				if (hasProto())
					mbIsNull = getProto().getIsNull();
				else
					mbIsNull = true;
			}
		}

		return mbIsNull;
	}

	public String getStrValue() {
		if (getIsNull())
			return ""; // null string

		String sValue = "";

		TextNode poTextNode = getText(true, false, false);
		if (poTextNode != null) {
			sValue = poTextNode.getValue();
		}
		return sValue;
	}

	public ScriptTable getScriptTable() {
		return ContentScript.getScriptTable();
	}

	public void insertChild(Node poChild, Node poRefNode, boolean bValidate) {
		super.insertChild(poChild, poRefNode, bValidate);
		if (mbIsNullDetermined) {
			mbIsNullDetermined = false; // reset null
			removeXsiNilAttribute();
		}
	}

	/** @exclude */
	public void resetPostLoadXML() {
		mbIsNullDetermined = false;
		super.resetPostLoadXML();
	}

	/**
	 * This method is a helper function that returns whether two Contents have
	 * the same text value. For example if you had the following:
	 * 
	 * 0 and 0
	 * 
	 * This method will return true, as their content translated to text are the
	 * same.
	 * 
	 * (case-sensitive, and considering the IsContentNull setting of both
	 * nodes).
	 * 
	 * @param compare -
	 *            the Content node to compare with
	 * @return true if the Content nodes are equal
	 */
	public boolean sameText(Content compare) {
		boolean bRC = false;

		// First Check if they are both null
		boolean bNull = getIsNull();

		boolean bOtherNull = compare.getIsNull();

		if (bNull && bOtherNull)
			bRC = true;
		else {
			// OK, they are not both null, so let's see
			// if their string representations are the same.
			String sValue = toString();
			String sOtherValue = compare.toString();

			if (sValue.equals(sOtherValue))
				bRC = true;
		}

		return bRC;
	}

	/**
	 * Sets the null state of the node
	 * @param bNull if true, set to null
	 * @param bNotify if true, notify peers of change
	 * @param bDefault if false make sure this node is marked as not default 
	 * @exclude
	 */
	public void setIsNull(boolean bNull, boolean bNotify/* = true */, boolean bDefault/* = false */) {
		if (getIsNull() == bNull)
			return;

		if (bNull) {
			// clear any value
			setStrValue("", false, false);

			// add xsi null attr to this element
			setXsiNilAttribute("true");
		} else {
			// add xsi null attr to this element
			setXsiNilAttribute("false");
		}

		mbIsNullDetermined = true;
		mbIsNull = bNull;

		if (!bDefault)
			makeNonDefault(false);
		
		if (bNotify)
			notifyPeers(VALUE_CHANGED, "", null);
	}

	public void setStrValue(String sText, boolean bNotify/* = true */, boolean bDefault /* = false */) {
		// UNDO(XFAXMLUndo, (this));

		if (sText == null) {
			setIsNull(true, bNotify,false);
			return;
		}

		if (mbIsNullDetermined) {
			mbIsNull = false;
			removeXsiNilAttribute();
		}

		// remove all children other than the first TextNode.
		TextNode textNode = null;
		Node nextChild;
		for (Node child = getFirstXFAChild(); child != null; child = nextChild) {
			nextChild = child.getNextXFASibling();
			
			if (textNode == null && child instanceof TextNode)
				textNode = (TextNode)child;
			else
				child.remove();
		}
		
		// Javaport: use getText rather than defaultElement.
		if (textNode == null)
			textNode = getText(false, true, false);

		// Pass FALSE so that textNode doesn't notify.  We're about to do that.
		textNode.setValue(sText, false, bDefault);

		if (bNotify)
			notifyPeers(VALUE_CHANGED, "", null);
	}
	//CL#710206
	public void setValue(String sValue, boolean bFromData, boolean bNotify, boolean bDefault) {
		setStrValue(sValue, bNotify, bDefault);
	}
	/**
	 * Return the value of the content as a string
	 * 
	 * @return the string representation of the value.
	 */
	public String toString() {
		// to String should be implemented by all derived classes.
		return getStrValue();
	}

	/**
	 * Helper routine for compareVersions()
	 * @exclude from published api.
	*/
	protected boolean compareVersionsAttrHelper(Element oRollback, int eTag) {
		// In the template DOM, the contentType is prescriptive (it informs our context-sensitive
		// defaulting and empty merge), and is therefore first-class data.  
		//
		// However, in the form DOM, it just controls the _processing_ of the data, and is
		// meaningless when there is no data.  2256724 and 1930441
		//
		if (eTag == XFA.CONTENTTYPETAG)
		{
			if (getModel() != null && getModel().getName() == XFA.FORM)
			{
				Content oRollbackContent = (Content) oRollback;
				if (couldBeNull() && oRollbackContent != null && oRollbackContent.couldBeNull())
					return true;
			}
		}
		
		return super.compareVersionsAttrHelper(oRollback, eTag);
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy