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

com.adobe.xfa.configuration.ConfigurationModel 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.configuration;


import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.xml.sax.Attributes;

import com.adobe.xfa.AppModel;
import com.adobe.xfa.Attribute;
import com.adobe.xfa.ChildReln;
import com.adobe.xfa.ChildRelnInfo;
import com.adobe.xfa.Element;
import com.adobe.xfa.LogMessage;
import com.adobe.xfa.Model;
import com.adobe.xfa.Node;
import com.adobe.xfa.NodeList;
import com.adobe.xfa.Obj;
import com.adobe.xfa.SOMParser;
import com.adobe.xfa.STRS;
import com.adobe.xfa.Schema;
import com.adobe.xfa.StringAttr;
import com.adobe.xfa.TextNode;
import com.adobe.xfa.XFA;
import com.adobe.xfa.SOMParser.SomResultInfo;
import com.adobe.xfa.template.TemplateModel;
import com.adobe.xfa.ut.BooleanHolder;
import com.adobe.xfa.ut.ExFull;
import com.adobe.xfa.ut.MsgFormat;
import com.adobe.xfa.ut.MsgFormatPos;
import com.adobe.xfa.ut.Numeric;
import com.adobe.xfa.ut.Peer;
import com.adobe.xfa.ut.ResId;
import com.adobe.xfa.ut.FindBugsSuppress;
import com.adobe.xfa.ut.StringUtils;


/**
 * A class to model the collection of all XFA nodes that make
 * up form config.
 *
 * @author Ian Benedict Carreon
 * @author Mike Tardif (ported to Java)
 */
public final class ConfigurationModel extends Model { 

	private static final ConfigurationSchema gConfigurationSchema
										= new ConfigurationSchema();

	/**
	 * @see Model#createNode(int, Element, String, String, boolean)
	 *
	 * @exclude from published api.
	 */
	public Node createNode(int eTag, Element parent, String aName, String aNS, boolean bDoVersionCheck) {
		assert (aName != null);
		assert (aNS != null);
		// check what type of node to create.
		if (eTag == XFA.TEXTNODETAG) {
			Element oRet = getSchema().getInstance(eTag, this, parent, null, bDoVersionCheck);
			// set the default value for the node
			if (parent instanceof ConfigurationValue) {
				Element grandParent = parent.getXFAParent();
				if (grandParent != null) {
					Attribute sValue = getSchema().defaultAttribute(parent.getClassTag(), grandParent.getClassTag());
					oRet.setAttribute(sValue, XFA.VALUETAG);
				}
			}
			return oRet;
		}
		else if (eTag == XFA.CONFIGURATIONKEYTAG) {
			return new ConfigurationKey(parent, null);
		}
		else if (eTag == XFA.CONFIGURATIONVALUETAG) {
			return new ConfigurationValue(parent, null);
		}	
		Element oRet = getSchema().getInstance(eTag, this, parent, null, bDoVersionCheck);
		if (oRet.isValidAttr(XFA.NAMETAG, false, null)) {
			oRet.setName(aName);
		}
		return oRet;
	}
	
	/**
	 * @exclude from published api.
	 */
	public String getHeadNS() {
		return configurationNS();
	}

    /**
 	 * @exclude from published api.
	 */
	protected static Schema getModelSchema() {
		return gConfigurationSchema;
	}


    /**
	 * Gets the configuration model held within an XFA DOM hierarchy.
	 *
	 * @param appModel the application model.
	 *
	 * @param bCreateIfNotFound when set, create a model if necessary.
	 *
	 * @return the configuration model or null if none found.
	 */
	public static ConfigurationModel getConfigurationModel(AppModel appModel,
									boolean bCreateIfNotFound /* = false */) {
		
		ConfigurationModel configModel = (ConfigurationModel)Model.getNamedModel(appModel, XFA.CONFIG);
		
		if (bCreateIfNotFound && configModel == null) {
			ConfigurationModelFactory factory = new ConfigurationModelFactory();
			configModel = (ConfigurationModel) factory.createDOM((Element)appModel.getXmlPeer());
			configModel.setDocument(appModel.getDocument());
			
			appModel.notifyPeers(Peer.CHILD_ADDED, XFA.CONFIG, configModel);
		}
		
		return configModel;
	}


	/**
	 * Namespace
	 * @return The configuration namespace URI string
	 *
 	 * @exclude from published api.
	 */
	public static String configurationNS() {
		return STRS.XFACONFIGURATIONNS_CURRENT;
	}

	 
	/**
	 * Default Constructor.
	 *
 	 * @exclude from published api.
	 */
	public ConfigurationModel(Element parent, Node prevSibling) {
		super(parent, prevSibling, configurationNS(), XFA.CONFIG, XFA.CONFIG,
				STRS.DOLLARCONFIG, XFA.CONFIGTAG, XFA.CONFIG, getModelSchema());
	}
	
	/**
	 * @see Model#getBaseNS()
	 *
	 * @exclude from published api.
	 */
	public String getBaseNS() {
	    return STRS.XFACONFIGURATIONNS;
	}

    /**
	 * @see Model#postLoad()
	 *
 	 * @exclude from published api.
	 */
	protected void postLoad() {
		postLoadFixUp(this);
		//
		// Check if there is a previous ConfigurationModel in the AppModel
		// (one that is not equal to this ConfigurationModel).  If an earlier
		// one exists, we need to merge this one into it and delete this one.
		//
		ConfigurationModel oPrevConfigurationModel = null;
		AppModel appModel = getAppModel();
		if (appModel != null) {
			Node child = appModel.getFirstXFAChild();
			while (child != null) {
				if (child != this && child instanceof ConfigurationModel) {
					oPrevConfigurationModel = ((ConfigurationModel) child);
					break;
				}
				child = child.getNextXFASibling();
			}
		}
		if (oPrevConfigurationModel != null) {
			oPrevConfigurationModel.mergeModel(this);
			appModel.removeChild(this);
		}
	}

	/**
	 * @see Model#isVersionCompatible(int, int)
	 *
	 * @exclude from published api.
	 */
	public boolean isVersionCompatible(int nVersion, int nTargetVersion) {
		if (nVersion <= Schema.XFAVERSION_25)
			nVersion = Schema.XFAVERSION_25;
		if (nTargetVersion <= Schema.XFAVERSION_25)
			nTargetVersion = Schema.XFAVERSION_25;
		return super.isVersionCompatible(nVersion, nTargetVersion);
	}

	/**
	 * @see Element#getNS()
	 * 
	 * @exclude from published api.
	 */
	public String getNS() {
		int nVersion = getCurrentVersion();
		//
		// Check if there is a template in the AppModel.  If so
		// then we want to set the version of the configuration
		// based on the template.
		//
		AppModel appModel = getAppModel();
		if (appModel != null) {			
			for (Node child = appModel.getFirstXFAChild(); child != null; child = child.getNextXFASibling()) {
				if (child instanceof TemplateModel) {
					nVersion = ((TemplateModel)child).getCurrentVersion();
					break;
				}
			}
		}
		// if we have a version set use it. 
		if (nVersion > 0) {
			// config version tracks template version for 2.8, 2.9 and 3.0 but is limited to 3.0 for template==3.1
			if (nVersion > Schema.XFAVERSION_30)
				nVersion = Schema.XFAVERSION_30;
			// bumped to 2.6 for Acrobat 8.1
			else if (nVersion > Schema.XFAVERSION_25 && nVersion < Schema.XFAVERSION_28)
				nVersion = Schema.XFAVERSION_26;
			// the ns stayed the same between 1.0 and 2.5
			else if (nVersion <= Schema.XFAVERSION_25)
				nVersion = Schema.XFAVERSION_10;
			
			double dVersion = ((double) nVersion) / 10.0;
			String sNSBuf = getBaseNS() + Numeric.doubleToString(dVersion, 1, false) + '/';
			return sNSBuf.intern();
		}
		return super.getNS();
	}

	/**
	 * Gets the value of a configuration value node.
	 * 

* If the node doesn't exist, the default value will be returned. * * @param sSOM A SOM expression specifying the configuration value node. * @param isDefault a scalar which is set to true if the node * exists, and false if the node does not exist and * the value returned is a default value. * @return the retrieved attribute. */ public Attribute getConfigValue(String sSOM, BooleanHolder isDefault) { // // Set value to empty string by default // isDefault.value = false; Node oContextNode = getContext(); assert (oContextNode != null); List oLHSResult = new ArrayList(); SOMParser oParser = new SOMParser(null); oParser.resolve(oContextNode, sSOM, oLHSResult); // // Hurl if more than one element returned. // if (oLHSResult.size() > 1) throw new ExFull(ResId.SOMTypeException); else if (oLHSResult.size() == 1) { // // If propertyName is not empty, then it's a reference // to a property as opposed to a node. // SOMParser.SomResultInfo oSRI = oLHSResult.get(0); if (!StringUtils.isEmpty(oSRI.propertyName)) { // Assume it's a string property since we really have no idea. isDefault.value = true; return new StringAttr(oSRI.propertyName, oSRI.value.getString()); } // Not a property reference. It must be a reference to an // XFAConfigurationValue node. if (! (oSRI.object instanceof ConfigurationValue)) throw new ExFull(new MsgFormat(ResId.InvalidCommandlineOption, sSOM)); ConfigurationValue oConfigValue = (ConfigurationValue) oSRI.object; Attribute oValue = oConfigValue.getValue(isDefault); isDefault.value = ! isDefault.value; return oValue; } // // SOM expression not found in config - get default value. // tag name = class name // Node oParent = oContextNode; // // Walk down until we don't have any more xfa nodes. // String sChild = null; int nOffset = -1; String sTag = sSOM; while ((nOffset = sTag.indexOf('.')) >= 0) { sChild = sTag.substring(0, nOffset); Node oNode = oParent.resolveNode(sChild); if (oNode == null) break; oParent = oNode; sTag = sTag.substring(nOffset + 1); } // // Ensure we are in the config dom. // if (! (oParent instanceof ConfigurationKey)) return new StringAttr("",""); Schema oSchema = getSchema(); // // We now know we are under an unvalidated section // so return default config value. // if (oParent.isSameClass(XFA.CONFIGURATIONKEY)) { int eTag = XFA.getTag(sChild.intern()); return oSchema.defaultAttribute(eTag, XFA.CONFIGURATIONVALUETAG); } // // Walk down the virual tree. // int eParent = oParent.getClassTag(); while ((nOffset = sTag.indexOf('.')) >= 0) { sChild = sTag.substring(0, nOffset); // // Trim off any [..] // int nFoundAt = sChild.indexOf('['); if (nFoundAt >= 0) sChild = sChild.substring(0, nFoundAt); ChildRelnInfo oReln = null; int eChild = XFA.getTag(sChild.intern()); if (eChild >= 0) oReln = oSchema.getNodeSchema(eParent).getChildRelnInfo(eChild); // // If null then check if configkey is valid. // if (oReln == null) { oReln = oSchema.getNodeSchema(eParent).getChildRelnInfo(XFA.CONFIGURATIONKEYTAG); if (oReln == null) return new StringAttr("",""); eParent = XFA.CONFIGURATIONKEYTAG; break; } eParent = eChild; sTag = sTag.substring(nOffset + 1); } // // Trim off any [..] // int nFoundAt = sTag.indexOf('['); if (nFoundAt >= 0) sTag = sTag.substring(0, nFoundAt); int eTag = XFA.getTag(sTag.intern()); ChildRelnInfo oReln = null; if (eTag >= 0) oReln = oSchema.getNodeSchema(eParent).getChildRelnInfo(eTag); // // If null then check if configkey is valid. // if (oReln == null) { if (oSchema.getNodeSchema(eParent).getChildRelnInfo(XFA.CONFIGURATIONKEYTAG).getRelationship() == null) return new StringAttr("",""); } return getSchema().defaultAttribute(eTag, eParent); } /** * Gets the value of a configuration value node. *

* If the node doesn't exist, the default value will be returned. * * @param sSOM A SOM expression specifying the configuration value node. * @param sValue The retrieved value. * @return true if the node exists, and false if the node does not exist * and the value returned is a default value. */ public boolean getConfigValue(String sSOM, StringBuilder sValue) { BooleanHolder oRetBool = new BooleanHolder(); Attribute oValue = getConfigValue(sSOM, oRetBool); if (oValue != null) sValue.append(oValue); return oRetBool.value; } /** * @exclude from published api. */ public int getHeadVersion() { return Schema.XFAVERSION_CONFIGURATIONHEAD; } /** * Retrieve the common ConfigurationKey node. For a particular schema root. * The schema root must have the common property child. * * @param sSchemaName The name of the root of the schema. * @return The common ConfigurationKey, null if common is not a valid * property of the root node. * * @exclude from published api. */ public Element getCommonNode(String sSchemaName) { Element oRoot = null; if (sSchemaName != null) { for (Node child = getFirstXFAChild(); child != null; child = child.getNextXFASibling()) { if (child instanceof Element) { Element element = (Element)child; if (element.getName().equals(sSchemaName)) { oRoot = element; } } } sSchemaName = sSchemaName.intern(); } int eTag = XFA.getTag(sSchemaName); if (oRoot != null) { if (! oRoot.isValidElement(XFA.COMMONTAG, false)) return null; } else if (eTag >= 0 && isValidElement(eTag, false) && eTag != XFA.AGENTTAG) { // assume all valid children have a property called common oRoot = createElement(eTag, getName()); } else { // create agent oRoot = createElement(XFA.AGENTTAG, sSchemaName); } return oRoot.getElement(XFA.COMMONTAG, 0); } /** * Creates a unique path of nodes using a SOM expression starting from * the root node. * * Remark that the SOM expression must start with "config". For example * "config.present.common" * * @param sSOMExpression a string representing a SOM expression * @param bLeafIsKey if true, then the leaf node in the SOM expressio * will be a key, else a value. * @return a node which is the last entity in the SOM expression. */ Node createNodePath(String sSOMExpression, boolean bLeafIsKey /* = false */) { throw new ExFull(ResId.UNSUPPORTED_OPERATION, "ConfigurationModel#createNodePath"); //TODO SOMParser.SomResultInfo oResult // = resolveNodeCreate(sSOMExpression, CREATEACTION, bKey); // Node oNode = oResult.object; // if (oNode != null || !StringUtils.isEmpty(oResult.propertyName)) // return null; // return oNode; } /** * Create an element based on the parameters provided by the SAX handler. * * @param uri namespace for this element. * @param localName local name for this element. * @param qName qualified name for this element. * @param attributes structure containing attribute definitions. * @return a new Element created according to our schema. * * @exclude from published api. */ public Element createElement(Element parent, Node prevSibling, String uri, String localName, String qName, Attributes attributes, int lineNumber, String fileName) { Element oElement = super.createElement(parent, prevSibling, uri, localName, qName, attributes, lineNumber, fileName); int eClassTag = oElement.getElementClass(); if (eClassTag != XFA.INVALID_ELEMENT) { // // Hide all password elements. // if (eClassTag == XFA.USERPASSWORDTAG) oElement.isHidden(true); else if (eClassTag == XFA.MASTERPASSWORDTAG) oElement.isHidden(true); } return oElement; } /** * @exclude from published api. */ public void mergeModel(ConfigurationModel oModel) { // This XFA-Configuration model is locked from any changes. if(getLocked()) return; mergeNode(this, oModel); } /** * Remap a given tag to a new value. This gives a model a chance to remap a tag * to a new value after it's determined that the original wasn't valid in the current * context. This implementation simply returns XFA.CONFIGURATIONKEYTAG. It should * be clever enough to determine either KEY or VALUE in the same way that * XFAConfigurationModelImpl::getNodeType does on the C++ side, but that's not possible * here due to the single DOM. Post-load fix-ups should recategorize this KEY to a VALUE * when necessary. * * @param eTag the original input tag. * * @return the new remapped tag. * * @exclude from published api. */ public int remapTag(int eTag) { return XFA.CONFIGURATIONKEYTAG; } // logic for merging configuration nodes @FindBugsSuppress(code="ES") private void mergeNode(Node oDestNode, Node oSrcNode) { assert(oDestNode.getName() == oSrcNode.getName()); // Check lock tag. We don't bother calling isLocked because that looks up the // tree to check inheritance. Since we're recursing from the top down, and we // stop at the first locked node, that's overkill. if (oDestNode.getLocked()) { // // Issue a warning; XFA-Configuration node is not modifiable. // ExFull oErr = new ExFull(ResId.InvalidOverrideOperationException, oDestNode.getName()); addErrorList(oErr, LogMessage.MSG_WARNING, this); return; } try { if (oDestNode instanceof ConfigurationValue && oSrcNode instanceof ConfigurationValue) { ((ConfigurationValue) oDestNode).setValue(((ConfigurationValue) oSrcNode).getValue()); if (oDestNode instanceof ConfigurationUri) { assert(oSrcNode instanceof ConfigurationUri); ((ConfigurationUri) oDestNode).setConfigLocation(((ConfigurationUri) oSrcNode).getConfigLocation()); } copyAttributes((Element)oDestNode, (Element)oSrcNode); return; } Node oParent = oSrcNode; for (Node oTemp = oSrcNode.getFirstXFAChild(); oTemp != null; oTemp = oTemp.getNextXFASibling()) { if (!(oTemp instanceof Element)) continue; Element oSrcChild = (Element) oTemp; boolean bMerge = false; // false: recursively merge oDestChild, oSrcChild; // true: just append a copy of oSrcChild to oDestNode String sSrcChildName = oSrcChild.getName(); Node oDestChild = oDestNode.locateChildByName(sSrcChildName, 0); if (oDestChild != null) bMerge = true; // Get the child relationship of oSrcChild with its parent (oSrcNode). ChildReln oChildReln = ((Element) oParent).getChildReln(oSrcChild.getClassTag()); if (oChildReln != null) { int eOccurs = oChildReln.getOccurrence(); if (eOccurs == ChildReln.zeroOrMore) { if ( ! ((Element) oSrcChild).isValidAttr(XFA.NAMETAG, false, null)) { if (oSrcChild.getName() == XFA.EQUATE) { NodeList oDestChildren = oDestNode.getNodes(); // If a node with a duplicate "from" attribute is found, just copy the attributes // of oSrcChild over that node. If not found, append oSrcChild. Element oDuplicateFromNode = equateFindDuplicateFrom(oDestChildren, oSrcChild); if (oDuplicateFromNode != null) { copyAttributes(oDuplicateFromNode, oSrcChild); continue; // handled } } bMerge = false; // for zeroOrMore nodes, just append copy of node } } } if (bMerge) { mergeNode(oDestChild, oSrcChild); copyAttributes((Element) oDestChild, oSrcChild); oDestChild.makeNonDefault(false); } else { oSrcChild.clone((Element) oDestNode); } } } catch (ExFull oEx) { // An illegal value was encountered. Log a warning and continue with the rest. addErrorList(oEx, LogMessage.MSG_WARNING, this); } } private void copyAttributes(Element oDestNode, Element oSrcNode) { if (oDestNode.getLocked()) return; // // Replace all the attributes // int nSize = oSrcNode.getNumAttrs(); String sAttrVal; for (int i = 0; i < nSize; i++) { Attribute domAttr = oSrcNode.getAttr(i); String aAttr = domAttr.getLocalName(); boolean bHandled = loadSpecialAttribute(domAttr, aAttr, oDestNode, false); if (!bHandled) { int eTag = XFA.getAttributeTag(aAttr); if (eTag != -1 && oDestNode.isValidAttr(eTag, true, null)) { sAttrVal = domAttr.getAttrValue(); Attribute oProperty = new StringAttr(aAttr, sAttrVal); oDestNode.setAttribute(oProperty, eTag); } } } } // Special case when node is tag // Searches oDestChildren for a node whose "from" property is a // duplicate of the "from" property in oSrcChild. If found, returns // that node, else returns a NULL node. private Element equateFindDuplicateFrom(NodeList oDestChildren, Element oSrcChild) { Attribute oNodeAttr = oSrcChild.getAttribute(XFA.FROMTAG); String sNodeAttr = oNodeAttr.toString(); int i = 0; while (i < oDestChildren.length()) { Obj oTemp = oDestChildren.item(i); if (!(oTemp instanceof Element)) continue; Element oDestChild = (Element) oTemp; Attribute oAttr = oDestChild.getAttribute(XFA.FROMTAG); String sAttr = oAttr.toString(); if (sAttr.equals(sNodeAttr)) return oDestChild; i++; } return null; // no duplicate "from" found } /** * postLoadFixUp is called from postLoad(). It traverses the entire config * DOM and replaces ConfigurationKeys that have no children, have or a * single #text child, with ConfigurationValues. This is to match the C++ * implementation, which has the luxury of looking at the XML DOM tree to * determine whether there are children or not, in order to decide whether * to create a Key or Value. * * @param node the Node to be fixed up. */ private void postLoadFixUp(Node node) { if (loadSpecialNode(node.getXFAParent(), node, false)) return; // If a ConfigurationKey has no children or a single #text child, it should have been a ConfigurationValue, // so replace it after the fact. if (node.getClassTag() == XFA.CONFIGURATIONKEYTAG) { if (node.getFirstXMLChild() == null) { Element parent = node.getXFAParent(); Element cv = new ConfigurationValue(parent, node, XFA.CONFIGURATIONVALUETAG, node.getName()); parent.removeChild(node); node = cv; // Replace node with the new ConfigurationValue and fall through. } else { Node child = node.getFirstXMLChild(); if (child instanceof TextNode && child.getNextXMLSibling() == null) { Element parent = node.getXFAParent(); Element cv = new ConfigurationValue(parent, node, XFA.CONFIGURATIONVALUETAG, node.getName()); cv.appendChild(child); parent.removeChild(node); node = cv; // Replace node with the new ConfigurationValue and fall through. } } } if (node instanceof ConfigurationValue) { // Verify that loaded values are valid by calling getValue(). If not valid, // issue a warning and set the ConfigurationValue to the default value. try { ((ConfigurationValue)node).getValue(); } catch (ExFull e) { String sOldValue = ""; Node textNode = node.getFirstXFAChild(); if (textNode instanceof TextNode) sOldValue = ((TextNode)textNode).getValue(); String sNewValue = ""; Element parent = node.getXFAParent(); if (parent != null) { Attribute newValue = getSchema().defaultAttribute(node.getClassTag(), parent.getClassTag()); ((ConfigurationValue)node).setValue(newValue); sNewValue = newValue.toString(); } // "Invalid value '%1' specified for element '%2'. Default value of '%3' will be used." MsgFormatPos message = new MsgFormatPos(ResId.FoundBadElementValueException); message.format(sOldValue); message.format(node.getName()); message.format(sNewValue); ExFull err = new ExFull(message); addErrorList(err, LogMessage.MSG_WARNING, this); } } if (node instanceof Element) { Element element = (Element)node; final int nAttributes = element.getNumAttrs(); for (int i = 0; i < nAttributes; i++) { Attribute attr = element.getAttr(i); /* boolean bHandled = */ loadSpecialAttribute(attr, attr.getLocalName(), element, false); } } // Check for locked nodes. Element parent = node.getXFAParent(); if (parent != null && parent.getLocked()) node.setLocked(true); else if (node instanceof Element) { Element e = (Element)node; Attribute locked = e.getAttribute(XFA.LOCKTAG, true, false); if (locked != null && locked.getAttrValue().equals("1")) e.setLocked(true); } // Recursively apply fix to children. Node child = node.getFirstXMLChild(); while (child != null) { Node next = child.getNextXMLSibling(); postLoadFixUp(child); child = next; } } /** * @see com.adobe.xfa.Model#publish(com.adobe.xfa.Model.Publisher) * @exclude from published api. */ public boolean publish(Publisher publisher) { // call static, recursive version Map fileRefCache = new HashMap(); publishNode(publisher, this, fileRefCache); return super.publish(publisher); } // static, recursive version of publish() private static void publishNode(Publisher publisher, Node node, Map fileRefCache) { if (node.isSameClass(XFA.URITAG)) { if (node.getXFAParent().isSameClass(XFA.XSLTAG) || node.getXFAParent().isSameClass(XFA.OUTPUTXSLTAG)) { if (node.getXFAChildCount() == 1) { TextNode textNode = (TextNode)node.getFirstXFAChild(); String sFileRef = textNode.getValue(); String sNewFileRef = fileRefCache.get(sFileRef); if (StringUtils.isEmpty(sNewFileRef)) { // call publisher's virtual method updateExternalRef() to get a new value sNewFileRef = publisher.updateExternalRef(node, XFA.TEXTNODETAG, sNewFileRef); fileRefCache.put(sFileRef, sNewFileRef); } if (!sFileRef.equals(sNewFileRef)) textNode.setValue(sNewFileRef, true, false); } } } for (Node child = node.getFirstXFAChild(); child != null; child = child.getNextXFASibling()) { publishNode(publisher, child, fileRefCache); } } /** * @see Node#canCreateChild(boolean, String) * * @exclude from published api. */ protected boolean canCreateChild(boolean bIsLeaf, String aName) { return true; } /** * @see Node#createChild(boolean, String) * * @exclude from published api. */ @FindBugsSuppress(code="ES") protected Node createChild(boolean bIsLeaf, String aName) { Node oNode; int eClassTag = XFA.getTag(aName); if (eClassTag >= 0 && isValidElement(eClassTag, false)) oNode = getModel().createElement(this, null, null, aName, aName, null, 0, null); else if (bIsLeaf) oNode = getModel().createElement(XFA.CONFIGURATIONVALUETAG, aName); else oNode = getModel().createElement(XFA.CONFIGURATIONKEYTAG, aName); return oNode; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy