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

com.adobe.xfa.form.FormChoiceListField Maven / Gradle / Ivy

There is a newer version: 2024.11.18751.20241128T090041Z-241100
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.form;

import com.adobe.xfa.Attribute;
import com.adobe.xfa.Chars;
import com.adobe.xfa.Document;
import com.adobe.xfa.Element;
import com.adobe.xfa.Generator;
import com.adobe.xfa.Model;
import com.adobe.xfa.Node;
import com.adobe.xfa.STRS;
import com.adobe.xfa.StringAttr;
import com.adobe.xfa.TextNode;
import com.adobe.xfa.XFA;
import com.adobe.xfa.XMLMultiSelectNode;
import com.adobe.xfa.content.Content;
import com.adobe.xfa.content.ExDataValue;
import com.adobe.xfa.content.TextValue;
import com.adobe.xfa.data.DataModel;
import com.adobe.xfa.data.DataNode;
import com.adobe.xfa.ut.StringUtils;


/**
 * @exclude from public api.
 */
public class FormChoiceListField extends FormField {
	
	public FormChoiceListField(Element parent, Node prevSibling) {
		super(parent, prevSibling);
	}

	// --------------------------------------------------
	// Overridden methods of FormField
	// --------------------------------------------------
	void setDataNode(DataNode dataNode,
			boolean bUpdateData /* = false */,
			boolean bPeerNode /* = true */, String sConnectPicture /* = "" */,
			boolean bDefault /* = true */ /* CL#708930 */) {
		
		// remove old listener
		if (getFormDataListener() != null && bPeerNode)
			setFormDataListener(null);

		// Type and null check
		if (dataNode == null || dataNode.getClassTag() != XFA.DATAGROUPTAG)
			return;

		// Establish a peer relationship with the data node
		if (bPeerNode)
			setFormDataListener(new FormDataListener(this, (DataNode)dataNode));

		if (bPeerNode && null != getFormDataListener())
			getFormDataListener().deafen();

		if (bUpdateData)
			setData(dataNode);
		else
			setFromData(dataNode);

		if (bPeerNode && null != getFormDataListener())
			getFormDataListener().unDeafen();
	}

	/**
	 * @see Element#getIsNull()
	 */
	public boolean getIsNull(boolean bCheckData) {

		DataNode dataNode = getDataNode();
		if (bCheckData && dataNode != null)
			return dataNode.getIsNull();

		Element value = getElement(XFA.VALUETAG, true, 0, false, false);
		if (value != null) {
			Content content = (Content)value.getOneOfChild(true, false);
			if (content == null)
				return true;
		
			if (content.getIsNull())
				return true;
		
			if (!content.couldBeNull())
				return false;
		}
		else 
			return true;

		return false;
	}
	

	public void setIsNull(boolean bNull, boolean bNotify /* = true */) {
		// since this binds to a dataGroup, don't do this
	}

	// override from formfield
	void setFromData(DataNode dataNode /* = null */) {
		boolean bDefault = true;
		if (dataNode == null) {
			bDefault = false; // if we have a null data node that means we are called via an update form peer call
			// in which case we should clear the default flag for this field
			FormDataListener listener = getFormDataListener();
			if (listener != null)
				dataNode = listener.getDataNode();
			else
				return;
		}
		
		if (!dataNode.isSameClass(XFA.DATAGROUP)) {
			// MultiSelect choice lists must bind to dataGroups
			return;
		}

		Element value = getElement(XFA.VALUETAG, 0);
			
		// if the value has no child, we create the  child node
		// the data then becomes its xml child
		Element valueContent = (Element)value.getOneOfChild();
		
		if (!valueContent.isSameClass(XFA.EXDATATAG)) {	
			String sValue = "";
			if (valueContent.isSameClass(XFA.TEXTTAG)) {
				TextNode textNode = ((Element)valueContent).getText(true, false, false);
				if (textNode != null)
					sValue = textNode.getValue();
			}

			// remove old content node
			valueContent.remove();

			// create exdata node
			Model model = getModel();
			Element exData = model.getSchema().getInstance(XFA.EXDATATAG, model, value, null, true);
				
			// add the content type text/xml to the new exData
			StringAttr oContentType = new StringAttr(XFA.CONTENTTYPE, STRS.TEXTXML);
			exData.setAttribute(oContentType, XFA.CONTENTTYPETAG);

			// set this exData as the child of the value
			value.setOneOfChild(exData);
			
			valueContent = (Element)value.getOneOfChild();

			if (!StringUtils.isEmpty(sValue)) {
				// add the xml child to the new exData
				Element exData2 = (Element)value.getOneOfChild();
				Node oMultiSelect = model.getSchema().getInstance(XFA.XMLMULTISELECTNODETAG, model, exData2, null, true);

				((XMLMultiSelectNode)oMultiSelect).setValue(sValue);
			}
		}
		else {
			// Get the contentType of the exData element.
			int index = valueContent.findAttr(null, XFA.CONTENTTYPE);
			if (index != -1) {
				String sContentType = valueContent.getAttrVal(index);
				if (!STRS.TEXTXML.equals(sContentType)) {
					StringAttr contentType = new StringAttr(XFA.CONTENTTYPE, STRS.TEXTXML);
					valueContent.setAttribute(contentType, XFA.CONTENTTYPETAG);
				}
			}
		}

		// xml fragment and copy it as a child of the XFADataValue
		Element fvNode = valueContent;
		Node dvNode = dataNode.getXmlPeer();
		
		// Import the xmlFragment from the data model to the form model
		Node importedNode = fvNode.getOwnerDocument().importNode(dvNode, true);
		
		//CL#722372 and 731044
		// bug 2680705 While digitally signing a Dynamic XFA Form, the DMB shows signature 
		// as invalid, if form contains a List Box which allows multiple selection.
		if (importedNode instanceof Element)
		{
			Attribute attr = ((Element)importedNode).getAttributeByName(XFA.DATANODE,false);
			if (null != attr)
			{
				String sValue = attr.getAttrValue();
				if(null != sValue && sValue.equals (XFA.DATAGROUP))
				{
					// we are removing this attribute here as it was added in 
					// XFADataGroupImpl::preSave, under condition (bAmbiguous && !bHasDDAttr)
					// this was causing problems while comparing Rollback and Current versions
					((Element)importedNode).removeAttr(attr.getNS(),attr.getName());
				}
			}
		}
		//CL#722372 and 731044

		// JavaPort: don't need to append to XML peer as in C++ since ExData is single-DOM
		
		// this will wrap the data in an #xml node
		((ExDataValue)valueContent).setContent(importedNode, bDefault);
	}

	void setData(DataNode dataNode /* = null */) {
		// null check
		if (dataNode == null) {
			FormDataListener listener = getFormDataListener();

			if (listener != null)
				dataNode = listener.getDataNode();

			if (dataNode == null)
				return;
		}

		if (dataNode.getClassTag() != XFA.DATAGROUPTAG) {
			// MultiSelect choice lists must bind to dataGroups
			return;
		}

		// delete all children of the data nodes
		while (dataNode.getFirstXFAChild() != null) {
			dataNode.getFirstXFAChild().remove();
		}

		if (getIsNull(false)) {
			// if the field has no value child, we create a value child
			// with an exData child. We also create the xml child of the
			// exData. Since the dataGroup is empty, we will then have 
			// a proper xml value for this choicelist, although it's empty

			Element value = getElement(XFA.VALUETAG, true, 0, false, false);
			if (value == null) {
				// create a value child
				value = getElement(XFA.VALUETAG, false, 0, false, false);
				
				// create the exData child of the new value
				Model model = getModel();
				Element exData = model.getSchema().getInstance(XFA.EXDATATAG, model, value, null, true);

				// add the content type text/xml to the new exData
				StringAttr contentType = new StringAttr(XFA.CONTENTTYPE, STRS.TEXTXML);
				exData.setAttribute(contentType, XFA.CONTENTTYPETAG);
				
				// add the xml child to the new exData
				model.getSchema().getInstance(XFA.XMLMULTISELECTNODETAG, model, exData, null, true);
			}
		}

		// Getting a field value involves traversing this
		// hierarchy
		//
		// 
		//   
		//		
		//			
		//				A
		//				...	
		//			
		//      
		//	 
		// 

		Element value = getElement(XFA.VALUETAG, 0);
		Node valueContent = value.getOneOfChild();		// hopefully exData

		// Fix for Bug #39261.  We were assuming that all children
		// of value had a textnode.  This is not true for arcs, lines
		// and rectangles.  Only nodes derived from Content exhibit
		// this behaviour.
		if (valueContent instanceof Content) {
			Node valueContentChild = null;
			
			// A content node is one of , , ,
			// , , 




© 2015 - 2024 Weber Informatics LLC | Privacy Policy