1 // Copyright 2014 PDFium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com 6 7 #include "xfa/fxfa/parser/xfa_document_datamerger_imp.h" 8 9 #include <map> 10 #include <vector> 11 12 #include "core/fxcrt/fx_ext.h" 13 #include "third_party/base/stl_util.h" 14 #include "xfa/fde/xml/fde_xml_imp.h" 15 #include "xfa/fxfa/parser/cxfa_document.h" 16 #include "xfa/fxfa/parser/cxfa_layoutprocessor.h" 17 #include "xfa/fxfa/parser/cxfa_occur.h" 18 #include "xfa/fxfa/parser/cxfa_scriptcontext.h" 19 #include "xfa/fxfa/parser/xfa_localemgr.h" 20 #include "xfa/fxfa/parser/xfa_object.h" 21 #include "xfa/fxfa/parser/xfa_resolvenode_rs.h" 22 #include "xfa/fxfa/parser/xfa_utils.h" 23 24 namespace { 25 26 class CXFA_TraverseStrategy_DDGroup { 27 public: 28 static CXFA_Node* GetFirstChild(CXFA_Node* pDDGroupNode) { 29 return pDDGroupNode->GetFirstChildByName(XFA_HASHCODE_Group); 30 } 31 static CXFA_Node* GetNextSibling(CXFA_Node* pDDGroupNode) { 32 return pDDGroupNode->GetNextSameNameSibling(XFA_HASHCODE_Group); 33 } 34 static CXFA_Node* GetParent(CXFA_Node* pDDGroupNode) { 35 return pDDGroupNode->GetNodeItem(XFA_NODEITEM_Parent); 36 } 37 }; 38 39 struct RecurseRecord { 40 CXFA_Node* pTemplateChild; 41 CXFA_Node* pDataChild; 42 }; 43 44 bool GetOccurInfo(CXFA_Node* pOccurNode, 45 int32_t& iMin, 46 int32_t& iMax, 47 int32_t& iInit) { 48 if (!pOccurNode) 49 return false; 50 51 CXFA_Occur occur(pOccurNode); 52 return occur.GetOccurInfo(iMin, iMax, iInit); 53 } 54 55 CXFA_Node* FormValueNode_CreateChild(CXFA_Node* pValueNode, XFA_Element iType) { 56 CXFA_Node* pChildNode = pValueNode->GetNodeItem(XFA_NODEITEM_FirstChild); 57 if (!pChildNode) { 58 if (iType == XFA_Element::Unknown) 59 return nullptr; 60 pChildNode = pValueNode->GetProperty(0, iType); 61 } 62 return pChildNode; 63 } 64 65 void FormValueNode_MatchNoneCreateChild(CXFA_Node* pFormNode) { 66 CXFA_WidgetData* pWidgetData = pFormNode->GetWidgetData(); 67 ASSERT(pWidgetData); 68 pWidgetData->GetUIType(); 69 } 70 71 bool FormValueNode_SetChildContent(CXFA_Node* pValueNode, 72 const CFX_WideString& wsContent, 73 XFA_Element iType = XFA_Element::Unknown) { 74 if (!pValueNode) 75 return false; 76 77 ASSERT(pValueNode->GetPacketID() == XFA_XDPPACKET_Form); 78 CXFA_Node* pChildNode = FormValueNode_CreateChild(pValueNode, iType); 79 if (!pChildNode) 80 return false; 81 82 switch (pChildNode->GetObjectType()) { 83 case XFA_ObjectType::ContentNode: { 84 CXFA_Node* pContentRawDataNode = 85 pChildNode->GetNodeItem(XFA_NODEITEM_FirstChild); 86 if (!pContentRawDataNode) { 87 XFA_Element element = XFA_Element::Sharptext; 88 if (pChildNode->GetElementType() == XFA_Element::ExData) { 89 CFX_WideString wsContentType; 90 pChildNode->GetAttribute(XFA_ATTRIBUTE_ContentType, wsContentType, 91 false); 92 if (wsContentType == L"text/html") 93 element = XFA_Element::SharpxHTML; 94 else if (wsContentType == L"text/xml") 95 element = XFA_Element::Sharpxml; 96 } 97 pContentRawDataNode = pChildNode->CreateSamePacketNode(element); 98 pChildNode->InsertChild(pContentRawDataNode); 99 } 100 pContentRawDataNode->SetCData(XFA_ATTRIBUTE_Value, wsContent); 101 break; 102 } 103 case XFA_ObjectType::NodeC: 104 case XFA_ObjectType::TextNode: 105 case XFA_ObjectType::NodeV: { 106 pChildNode->SetCData(XFA_ATTRIBUTE_Value, wsContent); 107 break; 108 } 109 default: 110 ASSERT(false); 111 break; 112 } 113 return true; 114 } 115 116 void CreateDataBinding(CXFA_Node* pFormNode, 117 CXFA_Node* pDataNode, 118 bool bDataToForm) { 119 pFormNode->SetObject(XFA_ATTRIBUTE_BindingNode, pDataNode); 120 pDataNode->AddBindItem(pFormNode); 121 XFA_Element eType = pFormNode->GetElementType(); 122 if (eType != XFA_Element::Field && eType != XFA_Element::ExclGroup) 123 return; 124 125 CXFA_WidgetData* pWidgetData = pFormNode->GetWidgetData(); 126 ASSERT(pWidgetData); 127 XFA_Element eUIType = pWidgetData->GetUIType(); 128 CXFA_Value defValue(pFormNode->GetProperty(0, XFA_Element::Value)); 129 if (!bDataToForm) { 130 CFX_WideString wsValue; 131 CFX_WideString wsFormattedValue; 132 switch (eUIType) { 133 case XFA_Element::ImageEdit: { 134 CXFA_Image image = defValue.GetImage(); 135 CFX_WideString wsContentType; 136 CFX_WideString wsHref; 137 if (image) { 138 image.GetContent(wsValue); 139 image.GetContentType(wsContentType); 140 image.GetHref(wsHref); 141 } 142 CFDE_XMLElement* pXMLDataElement = 143 static_cast<CFDE_XMLElement*>(pDataNode->GetXMLMappingNode()); 144 ASSERT(pXMLDataElement); 145 pWidgetData->GetFormatDataValue(wsValue, wsFormattedValue); 146 pDataNode->SetAttributeValue(wsValue, wsFormattedValue); 147 pDataNode->SetCData(XFA_ATTRIBUTE_ContentType, wsContentType); 148 if (!wsHref.IsEmpty()) 149 pXMLDataElement->SetString(L"href", wsHref); 150 151 break; 152 } 153 case XFA_Element::ChoiceList: 154 defValue.GetChildValueContent(wsValue); 155 if (pWidgetData->GetChoiceListOpen() == XFA_ATTRIBUTEENUM_MultiSelect) { 156 std::vector<CFX_WideString> wsSelTextArray; 157 pWidgetData->GetSelectedItemsValue(wsSelTextArray); 158 int32_t iSize = pdfium::CollectionSize<int32_t>(wsSelTextArray); 159 if (iSize >= 1) { 160 CXFA_Node* pValue = nullptr; 161 for (int32_t i = 0; i < iSize; i++) { 162 pValue = pDataNode->CreateSamePacketNode(XFA_Element::DataValue); 163 pValue->SetCData(XFA_ATTRIBUTE_Name, L"value"); 164 pValue->CreateXMLMappingNode(); 165 pDataNode->InsertChild(pValue); 166 pValue->SetCData(XFA_ATTRIBUTE_Value, wsSelTextArray[i]); 167 } 168 } else { 169 CFDE_XMLNode* pXMLNode = pDataNode->GetXMLMappingNode(); 170 ASSERT(pXMLNode->GetType() == FDE_XMLNODE_Element); 171 static_cast<CFDE_XMLElement*>(pXMLNode)->SetString(L"xfa:dataNode", 172 L"dataGroup"); 173 } 174 } else if (!wsValue.IsEmpty()) { 175 pWidgetData->GetFormatDataValue(wsValue, wsFormattedValue); 176 pDataNode->SetAttributeValue(wsValue, wsFormattedValue); 177 } 178 break; 179 case XFA_Element::CheckButton: 180 defValue.GetChildValueContent(wsValue); 181 if (wsValue.IsEmpty()) 182 break; 183 184 pWidgetData->GetFormatDataValue(wsValue, wsFormattedValue); 185 pDataNode->SetAttributeValue(wsValue, wsFormattedValue); 186 break; 187 case XFA_Element::ExclGroup: { 188 CXFA_Node* pChecked = nullptr; 189 CXFA_Node* pChild = pFormNode->GetNodeItem(XFA_NODEITEM_FirstChild); 190 for (; pChild; pChild = pChild->GetNodeItem(XFA_NODEITEM_NextSibling)) { 191 if (pChild->GetElementType() != XFA_Element::Field) 192 continue; 193 194 CXFA_Node* pValue = pChild->GetChild(0, XFA_Element::Value); 195 if (!pValue) 196 continue; 197 198 CXFA_Value valueChild(pValue); 199 valueChild.GetChildValueContent(wsValue); 200 if (wsValue.IsEmpty()) 201 continue; 202 203 CXFA_Node* pItems = pChild->GetChild(0, XFA_Element::Items); 204 if (!pItems) 205 continue; 206 207 CXFA_Node* pText = pItems->GetNodeItem(XFA_NODEITEM_FirstChild); 208 if (!pText) 209 continue; 210 211 CFX_WideString wsContent; 212 if (pText->TryContent(wsContent) && (wsContent == wsValue)) { 213 pChecked = pChild; 214 wsFormattedValue = wsValue; 215 pDataNode->SetAttributeValue(wsValue, wsFormattedValue); 216 pFormNode->SetCData(XFA_ATTRIBUTE_Value, wsContent); 217 break; 218 } 219 } 220 if (!pChecked) 221 break; 222 223 pChild = pFormNode->GetNodeItem(XFA_NODEITEM_FirstChild); 224 for (; pChild; pChild = pChild->GetNodeItem(XFA_NODEITEM_NextSibling)) { 225 if (pChild == pChecked) 226 continue; 227 if (pChild->GetElementType() != XFA_Element::Field) 228 continue; 229 230 CXFA_Node* pValue = pChild->GetProperty(0, XFA_Element::Value); 231 CXFA_Node* pItems = pChild->GetChild(0, XFA_Element::Items); 232 CXFA_Node* pText = 233 pItems ? pItems->GetNodeItem(XFA_NODEITEM_FirstChild) : nullptr; 234 if (pText) 235 pText = pText->GetNodeItem(XFA_NODEITEM_NextSibling); 236 237 CFX_WideString wsContent; 238 if (pText) 239 pText->TryContent(wsContent); 240 241 FormValueNode_SetChildContent(pValue, wsContent, XFA_Element::Text); 242 } 243 break; 244 } 245 case XFA_Element::NumericEdit: { 246 defValue.GetChildValueContent(wsValue); 247 if (wsValue.IsEmpty()) 248 break; 249 250 CFX_WideString wsOutput; 251 pWidgetData->NormalizeNumStr(wsValue, wsOutput); 252 wsValue = wsOutput; 253 pWidgetData->GetFormatDataValue(wsValue, wsFormattedValue); 254 pDataNode->SetAttributeValue(wsValue, wsFormattedValue); 255 CXFA_Node* pValue = pFormNode->GetProperty(0, XFA_Element::Value); 256 FormValueNode_SetChildContent(pValue, wsValue, XFA_Element::Float); 257 break; 258 } 259 default: 260 defValue.GetChildValueContent(wsValue); 261 if (wsValue.IsEmpty()) 262 break; 263 264 pWidgetData->GetFormatDataValue(wsValue, wsFormattedValue); 265 pDataNode->SetAttributeValue(wsValue, wsFormattedValue); 266 break; 267 } 268 return; 269 } 270 271 CFX_WideString wsXMLValue; 272 pDataNode->TryContent(wsXMLValue); 273 CFX_WideString wsNormalizeValue; 274 pWidgetData->GetNormalizeDataValue(wsXMLValue, wsNormalizeValue); 275 pDataNode->SetAttributeValue(wsNormalizeValue, wsXMLValue); 276 switch (eUIType) { 277 case XFA_Element::ImageEdit: { 278 FormValueNode_SetChildContent(defValue.GetNode(), wsNormalizeValue, 279 XFA_Element::Image); 280 CXFA_Image image = defValue.GetImage(); 281 if (image) { 282 CFDE_XMLElement* pXMLDataElement = 283 static_cast<CFDE_XMLElement*>(pDataNode->GetXMLMappingNode()); 284 ASSERT(pXMLDataElement); 285 CFX_WideString wsContentType; 286 CFX_WideString wsHref; 287 pXMLDataElement->GetString(L"xfa:contentType", wsContentType); 288 if (!wsContentType.IsEmpty()) { 289 pDataNode->SetCData(XFA_ATTRIBUTE_ContentType, wsContentType); 290 image.SetContentType(wsContentType); 291 } 292 pXMLDataElement->GetString(L"href", wsHref); 293 if (!wsHref.IsEmpty()) 294 image.SetHref(wsHref); 295 } 296 break; 297 } 298 case XFA_Element::ChoiceList: 299 if (pWidgetData->GetChoiceListOpen() == XFA_ATTRIBUTEENUM_MultiSelect) { 300 CXFA_NodeArray items; 301 pDataNode->GetNodeList(items); 302 int32_t iCounts = items.GetSize(); 303 if (iCounts > 0) { 304 wsNormalizeValue.clear(); 305 CFX_WideString wsItem; 306 for (int32_t i = 0; i < iCounts; i++) { 307 items[i]->TryContent(wsItem); 308 wsItem = (iCounts == 1) ? wsItem : wsItem + L"\n"; 309 wsNormalizeValue += wsItem; 310 } 311 CXFA_ExData exData = defValue.GetExData(); 312 ASSERT(exData); 313 exData.SetContentType(iCounts == 1 ? L"text/plain" : L"text/xml"); 314 } 315 FormValueNode_SetChildContent(defValue.GetNode(), wsNormalizeValue, 316 XFA_Element::ExData); 317 } else { 318 FormValueNode_SetChildContent(defValue.GetNode(), wsNormalizeValue, 319 XFA_Element::Text); 320 } 321 break; 322 case XFA_Element::CheckButton: 323 FormValueNode_SetChildContent(defValue.GetNode(), wsNormalizeValue, 324 XFA_Element::Text); 325 break; 326 case XFA_Element::ExclGroup: { 327 pWidgetData->SetSelectedMemberByValue(wsNormalizeValue.AsStringC(), false, 328 false, false); 329 break; 330 } 331 case XFA_Element::DateTimeEdit: 332 FormValueNode_SetChildContent(defValue.GetNode(), wsNormalizeValue, 333 XFA_Element::DateTime); 334 break; 335 case XFA_Element::NumericEdit: { 336 CFX_WideString wsPicture; 337 pWidgetData->GetPictureContent(wsPicture, XFA_VALUEPICTURE_DataBind); 338 if (wsPicture.IsEmpty()) { 339 CFX_WideString wsOutput; 340 pWidgetData->NormalizeNumStr(wsNormalizeValue, wsOutput); 341 wsNormalizeValue = wsOutput; 342 } 343 FormValueNode_SetChildContent(defValue.GetNode(), wsNormalizeValue, 344 XFA_Element::Float); 345 break; 346 } 347 case XFA_Element::Barcode: 348 case XFA_Element::Button: 349 case XFA_Element::PasswordEdit: 350 case XFA_Element::Signature: 351 case XFA_Element::TextEdit: 352 default: 353 FormValueNode_SetChildContent(defValue.GetNode(), wsNormalizeValue, 354 XFA_Element::Text); 355 break; 356 } 357 } 358 359 CXFA_Node* GetGlobalBinding(CXFA_Document* pDocument, uint32_t dwNameHash) { 360 auto it = pDocument->m_rgGlobalBinding.find(dwNameHash); 361 return it != pDocument->m_rgGlobalBinding.end() ? it->second : nullptr; 362 } 363 364 void RegisterGlobalBinding(CXFA_Document* pDocument, 365 uint32_t dwNameHash, 366 CXFA_Node* pDataNode) { 367 pDocument->m_rgGlobalBinding[dwNameHash] = pDataNode; 368 } 369 370 CXFA_Node* ScopeMatchGlobalBinding(CXFA_Node* pDataScope, 371 uint32_t dwNameHash, 372 XFA_Element eMatchDataNodeType, 373 bool bUpLevel) { 374 for (CXFA_Node *pCurDataScope = pDataScope, *pLastDataScope = nullptr; 375 pCurDataScope && pCurDataScope->GetPacketID() == XFA_XDPPACKET_Datasets; 376 pLastDataScope = pCurDataScope, 377 pCurDataScope = 378 pCurDataScope->GetNodeItem(XFA_NODEITEM_Parent)) { 379 for (CXFA_Node* pDataChild = pCurDataScope->GetFirstChildByName(dwNameHash); 380 pDataChild; 381 pDataChild = pDataChild->GetNextSameNameSibling(dwNameHash)) { 382 if (pDataChild == pLastDataScope || 383 (eMatchDataNodeType != XFA_Element::DataModel && 384 pDataChild->GetElementType() != eMatchDataNodeType) || 385 pDataChild->HasBindItem()) { 386 continue; 387 } 388 return pDataChild; 389 } 390 391 for (CXFA_Node* pDataChild = 392 pCurDataScope->GetFirstChildByClass(XFA_Element::DataGroup); 393 pDataChild; pDataChild = pDataChild->GetNextSameClassSibling( 394 XFA_Element::DataGroup)) { 395 CXFA_Node* pDataNode = ScopeMatchGlobalBinding(pDataChild, dwNameHash, 396 eMatchDataNodeType, false); 397 if (pDataNode) 398 return pDataNode; 399 } 400 if (!bUpLevel) 401 break; 402 } 403 return nullptr; 404 } 405 406 CXFA_Node* FindGlobalDataNode(CXFA_Document* pDocument, 407 CFX_WideStringC wsName, 408 CXFA_Node* pDataScope, 409 XFA_Element eMatchNodeType) { 410 if (wsName.IsEmpty()) 411 return nullptr; 412 413 uint32_t dwNameHash = FX_HashCode_GetW(wsName, false); 414 CXFA_Node* pBounded = GetGlobalBinding(pDocument, dwNameHash); 415 if (!pBounded) { 416 pBounded = 417 ScopeMatchGlobalBinding(pDataScope, dwNameHash, eMatchNodeType, true); 418 if (pBounded) 419 RegisterGlobalBinding(pDocument, dwNameHash, pBounded); 420 } 421 return pBounded; 422 } 423 424 CXFA_Node* FindOnceDataNode(CXFA_Document* pDocument, 425 CFX_WideStringC wsName, 426 CXFA_Node* pDataScope, 427 XFA_Element eMatchNodeType) { 428 if (wsName.IsEmpty()) 429 return nullptr; 430 431 uint32_t dwNameHash = FX_HashCode_GetW(wsName, false); 432 CXFA_Node* pLastDataScope = nullptr; 433 for (CXFA_Node* pCurDataScope = pDataScope; 434 pCurDataScope && pCurDataScope->GetPacketID() == XFA_XDPPACKET_Datasets; 435 pCurDataScope = pCurDataScope->GetNodeItem(XFA_NODEITEM_Parent)) { 436 for (CXFA_Node* pDataChild = pCurDataScope->GetFirstChildByName(dwNameHash); 437 pDataChild; 438 pDataChild = pDataChild->GetNextSameNameSibling(dwNameHash)) { 439 if (pDataChild == pLastDataScope || pDataChild->HasBindItem() || 440 (eMatchNodeType != XFA_Element::DataModel && 441 pDataChild->GetElementType() != eMatchNodeType)) { 442 continue; 443 } 444 return pDataChild; 445 } 446 pLastDataScope = pCurDataScope; 447 } 448 return nullptr; 449 } 450 451 CXFA_Node* FindDataRefDataNode(CXFA_Document* pDocument, 452 CFX_WideStringC wsRef, 453 CXFA_Node* pDataScope, 454 XFA_Element eMatchNodeType, 455 CXFA_Node* pTemplateNode, 456 bool bForceBind, 457 bool bUpLevel) { 458 uint32_t dFlags = XFA_RESOLVENODE_Children | XFA_RESOLVENODE_BindNew; 459 if (bUpLevel || wsRef != L"name") 460 dFlags |= (XFA_RESOLVENODE_Parent | XFA_RESOLVENODE_Siblings); 461 462 XFA_RESOLVENODE_RS rs; 463 pDocument->GetScriptContext()->ResolveObjects(pDataScope, wsRef, rs, dFlags, 464 pTemplateNode); 465 if (rs.dwFlags == XFA_RESOLVENODE_RSTYPE_CreateNodeAll || 466 rs.dwFlags == XFA_RESOLVENODE_RSTYPE_CreateNodeMidAll || 467 rs.nodes.GetSize() > 1) { 468 return pDocument->GetNotBindNode(rs.nodes); 469 } 470 471 if (rs.dwFlags == XFA_RESOLVENODE_RSTYPE_CreateNodeOne) { 472 CXFA_Object* pObject = (rs.nodes.GetSize() > 0) ? rs.nodes[0] : nullptr; 473 CXFA_Node* pNode = ToNode(pObject); 474 return (bForceBind || !pNode || !pNode->HasBindItem()) ? pNode : nullptr; 475 } 476 return nullptr; 477 } 478 479 bool NeedGenerateForm(CXFA_Node* pTemplateChild, bool bUseInstanceManager) { 480 XFA_Element eType = pTemplateChild->GetElementType(); 481 if (eType == XFA_Element::Variables) 482 return true; 483 if (pTemplateChild->IsContainerNode()) 484 return false; 485 if (eType == XFA_Element::Proto || 486 (bUseInstanceManager && eType == XFA_Element::Occur)) { 487 return false; 488 } 489 return true; 490 } 491 492 CXFA_Node* CloneOrMergeInstanceManager(CXFA_Document* pDocument, 493 CXFA_Node* pFormParent, 494 CXFA_Node* pTemplateNode, 495 CXFA_NodeArray& subforms) { 496 CFX_WideStringC wsSubformName = pTemplateNode->GetCData(XFA_ATTRIBUTE_Name); 497 CFX_WideString wsInstMgrNodeName = L"_" + wsSubformName; 498 uint32_t dwInstNameHash = 499 FX_HashCode_GetW(wsInstMgrNodeName.AsStringC(), false); 500 CXFA_Node* pExistingNode = XFA_DataMerge_FindFormDOMInstance( 501 pDocument, XFA_Element::InstanceManager, dwInstNameHash, pFormParent); 502 if (pExistingNode) { 503 uint32_t dwNameHash = pTemplateNode->GetNameHash(); 504 for (CXFA_Node* pNode = 505 pExistingNode->GetNodeItem(XFA_NODEITEM_NextSibling); 506 pNode;) { 507 XFA_Element eCurType = pNode->GetElementType(); 508 if (eCurType == XFA_Element::InstanceManager) 509 break; 510 511 if ((eCurType != XFA_Element::Subform) && 512 (eCurType != XFA_Element::SubformSet)) { 513 pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling); 514 continue; 515 } 516 if (dwNameHash != pNode->GetNameHash()) 517 break; 518 519 CXFA_Node* pNextNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling); 520 pFormParent->RemoveChild(pNode); 521 subforms.Add(pNode); 522 pNode = pNextNode; 523 } 524 pFormParent->RemoveChild(pExistingNode); 525 pFormParent->InsertChild(pExistingNode); 526 pExistingNode->ClearFlag(XFA_NodeFlag_UnusedNode); 527 pExistingNode->SetTemplateNode(pTemplateNode); 528 return pExistingNode; 529 } 530 531 CXFA_Node* pNewNode = 532 pDocument->CreateNode(XFA_XDPPACKET_Form, XFA_Element::InstanceManager); 533 wsInstMgrNodeName = L"_" + pTemplateNode->GetCData(XFA_ATTRIBUTE_Name); 534 pNewNode->SetCData(XFA_ATTRIBUTE_Name, wsInstMgrNodeName); 535 pFormParent->InsertChild(pNewNode, nullptr); 536 pNewNode->SetTemplateNode(pTemplateNode); 537 return pNewNode; 538 } 539 540 CXFA_Node* FindMatchingDataNode( 541 CXFA_Document* pDocument, 542 CXFA_Node* pTemplateNode, 543 CXFA_Node* pDataScope, 544 bool& bAccessedDataDOM, 545 bool bForceBind, 546 CXFA_NodeIteratorTemplate<CXFA_Node, 547 CXFA_TraverseStrategy_XFAContainerNode>* 548 pIterator, 549 bool& bSelfMatch, 550 XFA_ATTRIBUTEENUM& eBindMatch, 551 bool bUpLevel) { 552 bool bOwnIterator = false; 553 if (!pIterator) { 554 bOwnIterator = true; 555 pIterator = new CXFA_NodeIteratorTemplate< 556 CXFA_Node, CXFA_TraverseStrategy_XFAContainerNode>(pTemplateNode); 557 } 558 559 CXFA_Node* pResult = nullptr; 560 for (CXFA_Node* pCurTemplateNode = pIterator->GetCurrent(); 561 pCurTemplateNode;) { 562 XFA_Element eMatchNodeType; 563 switch (pCurTemplateNode->GetElementType()) { 564 case XFA_Element::Subform: 565 eMatchNodeType = XFA_Element::DataGroup; 566 break; 567 case XFA_Element::Field: { 568 eMatchNodeType = XFA_FieldIsMultiListBox(pCurTemplateNode) 569 ? XFA_Element::DataGroup 570 : XFA_Element::DataValue; 571 } break; 572 case XFA_Element::ExclGroup: 573 eMatchNodeType = XFA_Element::DataValue; 574 break; 575 default: 576 pCurTemplateNode = pIterator->MoveToNext(); 577 continue; 578 } 579 CXFA_Node* pTemplateNodeOccur = 580 pCurTemplateNode->GetFirstChildByClass(XFA_Element::Occur); 581 int32_t iMin, iMax, iInit; 582 if (pTemplateNodeOccur && 583 GetOccurInfo(pTemplateNodeOccur, iMin, iMax, iInit) && iMax == 0) { 584 pCurTemplateNode = pIterator->MoveToNext(); 585 continue; 586 } 587 588 CXFA_Node* pTemplateNodeBind = 589 pCurTemplateNode->GetFirstChildByClass(XFA_Element::Bind); 590 XFA_ATTRIBUTEENUM eMatch = 591 pTemplateNodeBind ? pTemplateNodeBind->GetEnum(XFA_ATTRIBUTE_Match) 592 : XFA_ATTRIBUTEENUM_Once; 593 eBindMatch = eMatch; 594 switch (eMatch) { 595 case XFA_ATTRIBUTEENUM_None: 596 pCurTemplateNode = pIterator->MoveToNext(); 597 continue; 598 case XFA_ATTRIBUTEENUM_Global: 599 bAccessedDataDOM = true; 600 if (!bForceBind) { 601 pCurTemplateNode = pIterator->MoveToNext(); 602 continue; 603 } 604 if (eMatchNodeType == XFA_Element::DataValue || 605 (eMatchNodeType == XFA_Element::DataGroup && 606 XFA_FieldIsMultiListBox(pTemplateNodeBind))) { 607 CXFA_Node* pGlobalBindNode = FindGlobalDataNode( 608 pDocument, pCurTemplateNode->GetCData(XFA_ATTRIBUTE_Name), 609 pDataScope, eMatchNodeType); 610 if (!pGlobalBindNode) { 611 pCurTemplateNode = pIterator->MoveToNext(); 612 continue; 613 } 614 pResult = pGlobalBindNode; 615 break; 616 } 617 case XFA_ATTRIBUTEENUM_Once: { 618 bAccessedDataDOM = true; 619 CXFA_Node* pOnceBindNode = FindOnceDataNode( 620 pDocument, pCurTemplateNode->GetCData(XFA_ATTRIBUTE_Name), 621 pDataScope, eMatchNodeType); 622 if (!pOnceBindNode) { 623 pCurTemplateNode = pIterator->MoveToNext(); 624 continue; 625 } 626 pResult = pOnceBindNode; 627 break; 628 } 629 case XFA_ATTRIBUTEENUM_DataRef: { 630 bAccessedDataDOM = true; 631 CXFA_Node* pDataRefBindNode = FindDataRefDataNode( 632 pDocument, pTemplateNodeBind->GetCData(XFA_ATTRIBUTE_Ref), 633 pDataScope, eMatchNodeType, pTemplateNode, bForceBind, bUpLevel); 634 if (pDataRefBindNode && 635 pDataRefBindNode->GetElementType() == eMatchNodeType) { 636 pResult = pDataRefBindNode; 637 } 638 if (!pResult) { 639 pCurTemplateNode = pIterator->SkipChildrenAndMoveToNext(); 640 continue; 641 } 642 break; 643 } 644 default: 645 break; 646 } 647 if (pCurTemplateNode == pTemplateNode && pResult) 648 bSelfMatch = true; 649 break; 650 } 651 if (bOwnIterator) 652 delete pIterator; 653 return pResult; 654 } 655 656 void SortRecurseRecord(CFX_ArrayTemplate<RecurseRecord>& rgRecords, 657 CXFA_Node* pDataScope, 658 bool bChoiceMode) { 659 int32_t iCount = rgRecords.GetSize(); 660 CFX_ArrayTemplate<RecurseRecord> rgResultRecord; 661 for (CXFA_Node* pChildNode = pDataScope->GetNodeItem(XFA_NODEITEM_FirstChild); 662 pChildNode; 663 pChildNode = pChildNode->GetNodeItem(XFA_NODEITEM_NextSibling)) { 664 for (int32_t i = 0; i < iCount; i++) { 665 CXFA_Node* pNode = rgRecords[i].pDataChild; 666 if (pChildNode == pNode) { 667 RecurseRecord sNewRecord = {rgRecords[i].pTemplateChild, pNode}; 668 rgResultRecord.Add(sNewRecord); 669 rgRecords.RemoveAt(i); 670 iCount--; 671 break; 672 } 673 } 674 if (bChoiceMode && rgResultRecord.GetSize() > 0) 675 break; 676 } 677 678 if (rgResultRecord.GetSize() > 0) { 679 if (!bChoiceMode) { 680 for (int32_t i = 0; i < iCount; i++) { 681 RecurseRecord sNewRecord = {rgRecords[i].pTemplateChild, 682 rgRecords[i].pDataChild}; 683 rgResultRecord.Add(sNewRecord); 684 } 685 } 686 rgRecords.RemoveAll(); 687 rgRecords.Copy(rgResultRecord); 688 } 689 } 690 691 CXFA_Node* CopyContainer_SubformSet(CXFA_Document* pDocument, 692 CXFA_Node* pTemplateNode, 693 CXFA_Node* pFormParentNode, 694 CXFA_Node* pDataScope, 695 bool bOneInstance, 696 bool bDataMerge) { 697 XFA_Element eType = pTemplateNode->GetElementType(); 698 CXFA_Node* pOccurNode = nullptr; 699 CXFA_Node* pFirstInstance = nullptr; 700 bool bUseInstanceManager = 701 pFormParentNode->GetElementType() != XFA_Element::Area; 702 CXFA_Node* pInstMgrNode = nullptr; 703 CXFA_NodeArray subformArray; 704 CXFA_NodeArray* pSearchArray = nullptr; 705 if (!bOneInstance && 706 (eType == XFA_Element::SubformSet || eType == XFA_Element::Subform)) { 707 pInstMgrNode = bUseInstanceManager ? CloneOrMergeInstanceManager( 708 pDocument, pFormParentNode, 709 pTemplateNode, subformArray) 710 : nullptr; 711 if (CXFA_Node* pOccurTemplateNode = 712 pTemplateNode->GetFirstChildByClass(XFA_Element::Occur)) { 713 pOccurNode = pInstMgrNode ? XFA_NodeMerge_CloneOrMergeContainer( 714 pDocument, pInstMgrNode, 715 pOccurTemplateNode, false, nullptr) 716 : pOccurTemplateNode; 717 } else if (pInstMgrNode) { 718 pOccurNode = pInstMgrNode->GetFirstChildByClass(XFA_Element::Occur); 719 if (pOccurNode) 720 pOccurNode->ClearFlag(XFA_NodeFlag_UnusedNode); 721 } 722 if (pInstMgrNode) { 723 pInstMgrNode->SetFlag(XFA_NodeFlag_Initialized, true); 724 pSearchArray = &subformArray; 725 if (pFormParentNode->GetElementType() == XFA_Element::PageArea) { 726 bOneInstance = true; 727 if (subformArray.GetSize() < 1) 728 pSearchArray = nullptr; 729 } else if ((pTemplateNode->GetNameHash() == 0) && 730 (subformArray.GetSize() < 1)) { 731 pSearchArray = nullptr; 732 } 733 } 734 } 735 736 int32_t iMax = 1; 737 int32_t iInit = 1; 738 int32_t iMin = 1; 739 if (!bOneInstance) 740 GetOccurInfo(pOccurNode, iMin, iMax, iInit); 741 742 XFA_ATTRIBUTEENUM eRelation = 743 eType == XFA_Element::SubformSet 744 ? pTemplateNode->GetEnum(XFA_ATTRIBUTE_Relation) 745 : XFA_ATTRIBUTEENUM_Ordered; 746 int32_t iCurRepeatIndex = 0; 747 XFA_ATTRIBUTEENUM eParentBindMatch = XFA_ATTRIBUTEENUM_None; 748 if (bDataMerge) { 749 CXFA_NodeIteratorTemplate<CXFA_Node, CXFA_TraverseStrategy_XFAContainerNode> 750 sNodeIterator(pTemplateNode); 751 bool bAccessedDataDOM = false; 752 if (eType == XFA_Element::SubformSet || eType == XFA_Element::Area) { 753 sNodeIterator.MoveToNext(); 754 } else { 755 std::map<CXFA_Node*, CXFA_Node*> subformMapArray; 756 CXFA_NodeArray nodeArray; 757 for (; iMax < 0 || iCurRepeatIndex < iMax; iCurRepeatIndex++) { 758 bool bSelfMatch = false; 759 XFA_ATTRIBUTEENUM eBindMatch = XFA_ATTRIBUTEENUM_None; 760 CXFA_Node* pDataNode = FindMatchingDataNode( 761 pDocument, pTemplateNode, pDataScope, bAccessedDataDOM, false, 762 &sNodeIterator, bSelfMatch, eBindMatch, true); 763 if (!pDataNode || sNodeIterator.GetCurrent() != pTemplateNode) 764 break; 765 766 eParentBindMatch = eBindMatch; 767 CXFA_Node* pSubformNode = XFA_NodeMerge_CloneOrMergeContainer( 768 pDocument, pFormParentNode, pTemplateNode, false, pSearchArray); 769 if (!pFirstInstance) 770 pFirstInstance = pSubformNode; 771 772 CreateDataBinding(pSubformNode, pDataNode, true); 773 ASSERT(pSubformNode); 774 subformMapArray[pSubformNode] = pDataNode; 775 nodeArray.Add(pSubformNode); 776 } 777 778 for (int32_t iIndex = 0; iIndex < nodeArray.GetSize(); iIndex++) { 779 CXFA_Node* pSubform = nodeArray[iIndex]; 780 CXFA_Node* pDataNode = nullptr; 781 auto it = subformMapArray.find(pSubform); 782 if (it != subformMapArray.end()) 783 pDataNode = it->second; 784 for (CXFA_Node* pTemplateChild = 785 pTemplateNode->GetNodeItem(XFA_NODEITEM_FirstChild); 786 pTemplateChild; pTemplateChild = pTemplateChild->GetNodeItem( 787 XFA_NODEITEM_NextSibling)) { 788 if (NeedGenerateForm(pTemplateChild, bUseInstanceManager)) { 789 XFA_NodeMerge_CloneOrMergeContainer(pDocument, pSubform, 790 pTemplateChild, true, nullptr); 791 } else if (pTemplateChild->IsContainerNode()) { 792 pDocument->DataMerge_CopyContainer(pTemplateChild, pSubform, 793 pDataNode, false, true, false); 794 } 795 } 796 } 797 subformMapArray.clear(); 798 } 799 800 for (; iMax < 0 || iCurRepeatIndex < iMax; iCurRepeatIndex++) { 801 bool bSelfMatch = false; 802 XFA_ATTRIBUTEENUM eBindMatch = XFA_ATTRIBUTEENUM_None; 803 if (!FindMatchingDataNode(pDocument, pTemplateNode, pDataScope, 804 bAccessedDataDOM, false, &sNodeIterator, 805 bSelfMatch, eBindMatch, true)) { 806 break; 807 } 808 if (eBindMatch == XFA_ATTRIBUTEENUM_DataRef && 809 eParentBindMatch == XFA_ATTRIBUTEENUM_DataRef) { 810 break; 811 } 812 813 if (eRelation == XFA_ATTRIBUTEENUM_Choice || 814 eRelation == XFA_ATTRIBUTEENUM_Unordered) { 815 CXFA_Node* pSubformSetNode = XFA_NodeMerge_CloneOrMergeContainer( 816 pDocument, pFormParentNode, pTemplateNode, false, pSearchArray); 817 ASSERT(pSubformSetNode); 818 if (!pFirstInstance) 819 pFirstInstance = pSubformSetNode; 820 821 CFX_ArrayTemplate<RecurseRecord> rgItemMatchList; 822 CFX_ArrayTemplate<CXFA_Node*> rgItemUnmatchList; 823 for (CXFA_Node* pTemplateChild = 824 pTemplateNode->GetNodeItem(XFA_NODEITEM_FirstChild); 825 pTemplateChild; pTemplateChild = pTemplateChild->GetNodeItem( 826 XFA_NODEITEM_NextSibling)) { 827 if (NeedGenerateForm(pTemplateChild, bUseInstanceManager)) { 828 XFA_NodeMerge_CloneOrMergeContainer(pDocument, pSubformSetNode, 829 pTemplateChild, true, nullptr); 830 } else if (pTemplateChild->IsContainerNode()) { 831 bSelfMatch = false; 832 eBindMatch = XFA_ATTRIBUTEENUM_None; 833 if (eRelation != XFA_ATTRIBUTEENUM_Ordered) { 834 CXFA_Node* pDataMatch = FindMatchingDataNode( 835 pDocument, pTemplateChild, pDataScope, bAccessedDataDOM, 836 false, nullptr, bSelfMatch, eBindMatch, true); 837 if (pDataMatch) { 838 RecurseRecord sNewRecord = {pTemplateChild, pDataMatch}; 839 if (bSelfMatch) 840 rgItemMatchList.InsertAt(0, sNewRecord); 841 else 842 rgItemMatchList.Add(sNewRecord); 843 } else { 844 rgItemUnmatchList.Add(pTemplateChild); 845 } 846 } else { 847 rgItemUnmatchList.Add(pTemplateChild); 848 } 849 } 850 } 851 852 switch (eRelation) { 853 case XFA_ATTRIBUTEENUM_Choice: { 854 ASSERT(rgItemMatchList.GetSize()); 855 SortRecurseRecord(rgItemMatchList, pDataScope, true); 856 pDocument->DataMerge_CopyContainer( 857 rgItemMatchList[0].pTemplateChild, pSubformSetNode, pDataScope, 858 false, true, true); 859 break; 860 } 861 case XFA_ATTRIBUTEENUM_Unordered: { 862 if (rgItemMatchList.GetSize()) { 863 SortRecurseRecord(rgItemMatchList, pDataScope, false); 864 for (int32_t i = 0, count = rgItemMatchList.GetSize(); i < count; 865 i++) { 866 pDocument->DataMerge_CopyContainer( 867 rgItemMatchList[i].pTemplateChild, pSubformSetNode, 868 pDataScope, false, true, true); 869 } 870 } 871 for (int32_t i = 0, count = rgItemUnmatchList.GetSize(); i < count; 872 i++) { 873 pDocument->DataMerge_CopyContainer(rgItemUnmatchList[i], 874 pSubformSetNode, pDataScope, 875 false, true, true); 876 } 877 break; 878 } 879 default: 880 break; 881 } 882 } else { 883 CXFA_Node* pSubformSetNode = XFA_NodeMerge_CloneOrMergeContainer( 884 pDocument, pFormParentNode, pTemplateNode, false, pSearchArray); 885 ASSERT(pSubformSetNode); 886 if (!pFirstInstance) 887 pFirstInstance = pSubformSetNode; 888 889 for (CXFA_Node* pTemplateChild = 890 pTemplateNode->GetNodeItem(XFA_NODEITEM_FirstChild); 891 pTemplateChild; pTemplateChild = pTemplateChild->GetNodeItem( 892 XFA_NODEITEM_NextSibling)) { 893 if (NeedGenerateForm(pTemplateChild, bUseInstanceManager)) { 894 XFA_NodeMerge_CloneOrMergeContainer(pDocument, pSubformSetNode, 895 pTemplateChild, true, nullptr); 896 } else if (pTemplateChild->IsContainerNode()) { 897 pDocument->DataMerge_CopyContainer(pTemplateChild, pSubformSetNode, 898 pDataScope, false, true, true); 899 } 900 } 901 } 902 } 903 904 if (iCurRepeatIndex == 0 && bAccessedDataDOM == false) { 905 int32_t iLimit = iMax; 906 if (pInstMgrNode && pTemplateNode->GetNameHash() == 0) { 907 iLimit = subformArray.GetSize(); 908 if (iLimit < iMin) 909 iLimit = iInit; 910 } 911 912 for (; (iLimit < 0 || iCurRepeatIndex < iLimit); iCurRepeatIndex++) { 913 if (pInstMgrNode) { 914 if (pSearchArray && pSearchArray->GetSize() < 1) { 915 if (pTemplateNode->GetNameHash() != 0) 916 break; 917 pSearchArray = nullptr; 918 } 919 } else if (!XFA_DataMerge_FindFormDOMInstance( 920 pDocument, pTemplateNode->GetElementType(), 921 pTemplateNode->GetNameHash(), pFormParentNode)) { 922 break; 923 } 924 CXFA_Node* pSubformNode = XFA_NodeMerge_CloneOrMergeContainer( 925 pDocument, pFormParentNode, pTemplateNode, false, pSearchArray); 926 ASSERT(pSubformNode); 927 if (!pFirstInstance) 928 pFirstInstance = pSubformNode; 929 930 for (CXFA_Node* pTemplateChild = 931 pTemplateNode->GetNodeItem(XFA_NODEITEM_FirstChild); 932 pTemplateChild; pTemplateChild = pTemplateChild->GetNodeItem( 933 XFA_NODEITEM_NextSibling)) { 934 if (NeedGenerateForm(pTemplateChild, bUseInstanceManager)) { 935 XFA_NodeMerge_CloneOrMergeContainer(pDocument, pSubformNode, 936 pTemplateChild, true, nullptr); 937 } else if (pTemplateChild->IsContainerNode()) { 938 pDocument->DataMerge_CopyContainer(pTemplateChild, pSubformNode, 939 pDataScope, false, true, true); 940 } 941 } 942 } 943 } 944 } 945 946 int32_t iMinimalLimit = iCurRepeatIndex == 0 ? iInit : iMin; 947 for (; iCurRepeatIndex < iMinimalLimit; iCurRepeatIndex++) { 948 CXFA_Node* pSubformSetNode = XFA_NodeMerge_CloneOrMergeContainer( 949 pDocument, pFormParentNode, pTemplateNode, false, pSearchArray); 950 ASSERT(pSubformSetNode); 951 if (!pFirstInstance) 952 pFirstInstance = pSubformSetNode; 953 954 bool bFound = false; 955 for (CXFA_Node* pTemplateChild = 956 pTemplateNode->GetNodeItem(XFA_NODEITEM_FirstChild); 957 pTemplateChild; pTemplateChild = pTemplateChild->GetNodeItem( 958 XFA_NODEITEM_NextSibling)) { 959 if (NeedGenerateForm(pTemplateChild, bUseInstanceManager)) { 960 XFA_NodeMerge_CloneOrMergeContainer(pDocument, pSubformSetNode, 961 pTemplateChild, true, nullptr); 962 } else if (pTemplateChild->IsContainerNode()) { 963 if (bFound && eRelation == XFA_ATTRIBUTEENUM_Choice) 964 continue; 965 966 pDocument->DataMerge_CopyContainer(pTemplateChild, pSubformSetNode, 967 pDataScope, false, bDataMerge, true); 968 bFound = true; 969 } 970 } 971 } 972 return pFirstInstance; 973 } 974 975 CXFA_Node* CopyContainer_Field(CXFA_Document* pDocument, 976 CXFA_Node* pTemplateNode, 977 CXFA_Node* pFormNode, 978 CXFA_Node* pDataScope, 979 bool bDataMerge, 980 bool bUpLevel) { 981 CXFA_Node* pFieldNode = XFA_NodeMerge_CloneOrMergeContainer( 982 pDocument, pFormNode, pTemplateNode, false, nullptr); 983 ASSERT(pFieldNode); 984 for (CXFA_Node* pTemplateChildNode = 985 pTemplateNode->GetNodeItem(XFA_NODEITEM_FirstChild); 986 pTemplateChildNode; pTemplateChildNode = pTemplateChildNode->GetNodeItem( 987 XFA_NODEITEM_NextSibling)) { 988 if (NeedGenerateForm(pTemplateChildNode, true)) { 989 XFA_NodeMerge_CloneOrMergeContainer(pDocument, pFieldNode, 990 pTemplateChildNode, true, nullptr); 991 } else if (pTemplateNode->GetElementType() == XFA_Element::ExclGroup && 992 pTemplateChildNode->IsContainerNode()) { 993 if (pTemplateChildNode->GetElementType() == XFA_Element::Field) { 994 CopyContainer_Field(pDocument, pTemplateChildNode, pFieldNode, nullptr, 995 false, true); 996 } 997 } 998 } 999 if (bDataMerge) { 1000 bool bAccessedDataDOM = false; 1001 bool bSelfMatch = false; 1002 XFA_ATTRIBUTEENUM eBindMatch; 1003 CXFA_Node* pDataNode = FindMatchingDataNode( 1004 pDocument, pTemplateNode, pDataScope, bAccessedDataDOM, true, nullptr, 1005 bSelfMatch, eBindMatch, bUpLevel); 1006 if (pDataNode) 1007 CreateDataBinding(pFieldNode, pDataNode, true); 1008 } else { 1009 FormValueNode_MatchNoneCreateChild(pFieldNode); 1010 } 1011 return pFieldNode; 1012 } 1013 1014 CXFA_Node* MaybeCreateDataNode(CXFA_Document* pDocument, 1015 CXFA_Node* pDataParent, 1016 XFA_Element eNodeType, 1017 const CFX_WideString& wsName) { 1018 if (!pDataParent) 1019 return nullptr; 1020 1021 CXFA_Node* pParentDDNode = pDataParent->GetDataDescriptionNode(); 1022 if (!pParentDDNode) { 1023 CXFA_Node* pDataNode = 1024 pDocument->CreateNode(XFA_XDPPACKET_Datasets, eNodeType); 1025 pDataNode->SetCData(XFA_ATTRIBUTE_Name, wsName); 1026 pDataNode->CreateXMLMappingNode(); 1027 pDataParent->InsertChild(pDataNode); 1028 pDataNode->SetFlag(XFA_NodeFlag_Initialized, false); 1029 return pDataNode; 1030 } 1031 1032 CXFA_NodeIteratorTemplate<CXFA_Node, CXFA_TraverseStrategy_DDGroup> sIterator( 1033 pParentDDNode); 1034 for (CXFA_Node* pDDGroupNode = sIterator.GetCurrent(); pDDGroupNode; 1035 pDDGroupNode = sIterator.MoveToNext()) { 1036 if (pDDGroupNode != pParentDDNode) { 1037 if (pDDGroupNode->GetElementType() != XFA_Element::DataGroup) 1038 continue; 1039 1040 CFX_WideString wsNamespace; 1041 if (!pDDGroupNode->TryNamespace(wsNamespace) || 1042 wsNamespace != L"http://ns.adobe.com/data-description/") { 1043 continue; 1044 } 1045 } 1046 CXFA_Node* pDDNode = pDDGroupNode->GetFirstChildByName(wsName.AsStringC()); 1047 if (!pDDNode) 1048 continue; 1049 if (pDDNode->GetElementType() != eNodeType) 1050 break; 1051 1052 CXFA_Node* pDataNode = 1053 pDocument->CreateNode(XFA_XDPPACKET_Datasets, eNodeType); 1054 pDataNode->SetCData(XFA_ATTRIBUTE_Name, wsName); 1055 pDataNode->CreateXMLMappingNode(); 1056 if (eNodeType == XFA_Element::DataValue && 1057 pDDNode->GetEnum(XFA_ATTRIBUTE_Contains) == 1058 XFA_ATTRIBUTEENUM_MetaData) { 1059 pDataNode->SetEnum(XFA_ATTRIBUTE_Contains, XFA_ATTRIBUTEENUM_MetaData); 1060 } 1061 pDataParent->InsertChild(pDataNode); 1062 pDataNode->SetDataDescriptionNode(pDDNode); 1063 pDataNode->SetFlag(XFA_NodeFlag_Initialized, false); 1064 return pDataNode; 1065 } 1066 return nullptr; 1067 } 1068 1069 void UpdateBindingRelations(CXFA_Document* pDocument, 1070 CXFA_Node* pFormNode, 1071 CXFA_Node* pDataScope, 1072 bool bDataRef, 1073 bool bParentDataRef) { 1074 bool bMatchRef = true; 1075 XFA_Element eType = pFormNode->GetElementType(); 1076 CXFA_Node* pDataNode = pFormNode->GetBindData(); 1077 if (eType == XFA_Element::Subform || eType == XFA_Element::ExclGroup || 1078 eType == XFA_Element::Field) { 1079 CXFA_Node* pTemplateNode = pFormNode->GetTemplateNode(); 1080 CXFA_Node* pTemplateNodeBind = 1081 pTemplateNode ? pTemplateNode->GetFirstChildByClass(XFA_Element::Bind) 1082 : nullptr; 1083 XFA_ATTRIBUTEENUM eMatch = 1084 pTemplateNodeBind ? pTemplateNodeBind->GetEnum(XFA_ATTRIBUTE_Match) 1085 : XFA_ATTRIBUTEENUM_Once; 1086 switch (eMatch) { 1087 case XFA_ATTRIBUTEENUM_None: 1088 if (!bDataRef || bParentDataRef) 1089 FormValueNode_MatchNoneCreateChild(pFormNode); 1090 break; 1091 case XFA_ATTRIBUTEENUM_Once: 1092 if (!bDataRef || bParentDataRef) { 1093 if (!pDataNode) { 1094 if (pFormNode->GetNameHash() != 0 && 1095 pFormNode->GetEnum(XFA_ATTRIBUTE_Scope) != 1096 XFA_ATTRIBUTEENUM_None) { 1097 XFA_Element eDataNodeType = (eType == XFA_Element::Subform || 1098 XFA_FieldIsMultiListBox(pFormNode)) 1099 ? XFA_Element::DataGroup 1100 : XFA_Element::DataValue; 1101 pDataNode = MaybeCreateDataNode( 1102 pDocument, pDataScope, eDataNodeType, 1103 CFX_WideString(pFormNode->GetCData(XFA_ATTRIBUTE_Name))); 1104 if (pDataNode) 1105 CreateDataBinding(pFormNode, pDataNode, false); 1106 } 1107 if (!pDataNode) 1108 FormValueNode_MatchNoneCreateChild(pFormNode); 1109 1110 } else { 1111 CXFA_Node* pDataParent = 1112 pDataNode->GetNodeItem(XFA_NODEITEM_Parent); 1113 if (pDataParent != pDataScope) { 1114 ASSERT(pDataParent); 1115 pDataParent->RemoveChild(pDataNode); 1116 pDataScope->InsertChild(pDataNode); 1117 } 1118 } 1119 } 1120 break; 1121 case XFA_ATTRIBUTEENUM_Global: 1122 if (!bDataRef || bParentDataRef) { 1123 uint32_t dwNameHash = pFormNode->GetNameHash(); 1124 if (dwNameHash != 0 && !pDataNode) { 1125 pDataNode = GetGlobalBinding(pDocument, dwNameHash); 1126 if (!pDataNode) { 1127 XFA_Element eDataNodeType = (eType == XFA_Element::Subform || 1128 XFA_FieldIsMultiListBox(pFormNode)) 1129 ? XFA_Element::DataGroup 1130 : XFA_Element::DataValue; 1131 CXFA_Node* pRecordNode = 1132 ToNode(pDocument->GetXFAObject(XFA_HASHCODE_Record)); 1133 pDataNode = MaybeCreateDataNode( 1134 pDocument, pRecordNode, eDataNodeType, 1135 CFX_WideString(pFormNode->GetCData(XFA_ATTRIBUTE_Name))); 1136 if (pDataNode) { 1137 CreateDataBinding(pFormNode, pDataNode, false); 1138 RegisterGlobalBinding(pDocument, pFormNode->GetNameHash(), 1139 pDataNode); 1140 } 1141 } else { 1142 CreateDataBinding(pFormNode, pDataNode, true); 1143 } 1144 } 1145 if (!pDataNode) 1146 FormValueNode_MatchNoneCreateChild(pFormNode); 1147 } 1148 break; 1149 case XFA_ATTRIBUTEENUM_DataRef: { 1150 bMatchRef = bDataRef; 1151 bParentDataRef = true; 1152 if (!pDataNode && bDataRef) { 1153 CFX_WideStringC wsRef = 1154 pTemplateNodeBind->GetCData(XFA_ATTRIBUTE_Ref); 1155 uint32_t dFlags = 1156 XFA_RESOLVENODE_Children | XFA_RESOLVENODE_CreateNode; 1157 XFA_RESOLVENODE_RS rs; 1158 pDocument->GetScriptContext()->ResolveObjects(pDataScope, wsRef, rs, 1159 dFlags, pTemplateNode); 1160 CXFA_Object* pObject = 1161 (rs.nodes.GetSize() > 0) ? rs.nodes[0] : nullptr; 1162 pDataNode = ToNode(pObject); 1163 if (pDataNode) { 1164 CreateDataBinding(pFormNode, pDataNode, 1165 rs.dwFlags == XFA_RESOVENODE_RSTYPE_ExistNodes); 1166 } else { 1167 FormValueNode_MatchNoneCreateChild(pFormNode); 1168 } 1169 } 1170 break; 1171 } 1172 default: 1173 break; 1174 } 1175 } 1176 1177 if (bMatchRef && 1178 (eType == XFA_Element::Subform || eType == XFA_Element::SubformSet || 1179 eType == XFA_Element::Area || eType == XFA_Element::PageArea || 1180 eType == XFA_Element::PageSet)) { 1181 for (CXFA_Node* pFormChild = 1182 pFormNode->GetNodeItem(XFA_NODEITEM_FirstChild); 1183 pFormChild; 1184 pFormChild = pFormChild->GetNodeItem(XFA_NODEITEM_NextSibling)) { 1185 if (!pFormChild->IsContainerNode()) 1186 continue; 1187 if (pFormChild->IsUnusedNode()) 1188 continue; 1189 1190 UpdateBindingRelations(pDocument, pFormChild, 1191 pDataNode ? pDataNode : pDataScope, bDataRef, 1192 bParentDataRef); 1193 } 1194 } 1195 } 1196 1197 void UpdateDataRelation(CXFA_Node* pDataNode, CXFA_Node* pDataDescriptionNode) { 1198 ASSERT(pDataDescriptionNode); 1199 for (CXFA_Node* pDataChild = pDataNode->GetNodeItem(XFA_NODEITEM_FirstChild); 1200 pDataChild; 1201 pDataChild = pDataChild->GetNodeItem(XFA_NODEITEM_NextSibling)) { 1202 uint32_t dwNameHash = pDataChild->GetNameHash(); 1203 if (!dwNameHash) 1204 continue; 1205 1206 CXFA_NodeIteratorTemplate<CXFA_Node, CXFA_TraverseStrategy_DDGroup> 1207 sIterator(pDataDescriptionNode); 1208 for (CXFA_Node* pDDGroupNode = sIterator.GetCurrent(); pDDGroupNode; 1209 pDDGroupNode = sIterator.MoveToNext()) { 1210 if (pDDGroupNode != pDataDescriptionNode) { 1211 if (pDDGroupNode->GetElementType() != XFA_Element::DataGroup) 1212 continue; 1213 1214 CFX_WideString wsNamespace; 1215 if (!pDDGroupNode->TryNamespace(wsNamespace) || 1216 wsNamespace != L"http://ns.adobe.com/data-description/") { 1217 continue; 1218 } 1219 } 1220 CXFA_Node* pDDNode = pDDGroupNode->GetFirstChildByName(dwNameHash); 1221 if (!pDDNode) 1222 continue; 1223 if (pDDNode->GetElementType() != pDataChild->GetElementType()) 1224 break; 1225 1226 pDataChild->SetDataDescriptionNode(pDDNode); 1227 UpdateDataRelation(pDataChild, pDDNode); 1228 break; 1229 } 1230 } 1231 } 1232 1233 } // namespace 1234 1235 CXFA_Node* XFA_DataMerge_FindFormDOMInstance(CXFA_Document* pDocument, 1236 XFA_Element eType, 1237 uint32_t dwNameHash, 1238 CXFA_Node* pFormParent) { 1239 CXFA_Node* pFormChild = pFormParent->GetNodeItem(XFA_NODEITEM_FirstChild); 1240 for (; pFormChild; 1241 pFormChild = pFormChild->GetNodeItem(XFA_NODEITEM_NextSibling)) { 1242 if (pFormChild->GetElementType() == eType && 1243 pFormChild->GetNameHash() == dwNameHash && pFormChild->IsUnusedNode()) { 1244 return pFormChild; 1245 } 1246 } 1247 return nullptr; 1248 } 1249 1250 CXFA_Node* XFA_NodeMerge_CloneOrMergeContainer(CXFA_Document* pDocument, 1251 CXFA_Node* pFormParent, 1252 CXFA_Node* pTemplateNode, 1253 bool bRecursive, 1254 CXFA_NodeArray* pSubformArray) { 1255 CXFA_Node* pExistingNode = nullptr; 1256 if (!pSubformArray) { 1257 pExistingNode = XFA_DataMerge_FindFormDOMInstance( 1258 pDocument, pTemplateNode->GetElementType(), 1259 pTemplateNode->GetNameHash(), pFormParent); 1260 } else if (pSubformArray->GetSize() > 0) { 1261 pExistingNode = pSubformArray->GetAt(0); 1262 pSubformArray->RemoveAt(0); 1263 } 1264 1265 if (pExistingNode) { 1266 if (pSubformArray) { 1267 pFormParent->InsertChild(pExistingNode); 1268 } else if (pExistingNode->IsContainerNode()) { 1269 pFormParent->RemoveChild(pExistingNode); 1270 pFormParent->InsertChild(pExistingNode); 1271 } 1272 pExistingNode->ClearFlag(XFA_NodeFlag_UnusedNode); 1273 pExistingNode->SetTemplateNode(pTemplateNode); 1274 if (bRecursive && pExistingNode->GetElementType() != XFA_Element::Items) { 1275 for (CXFA_Node* pTemplateChild = 1276 pTemplateNode->GetNodeItem(XFA_NODEITEM_FirstChild); 1277 pTemplateChild; pTemplateChild = pTemplateChild->GetNodeItem( 1278 XFA_NODEITEM_NextSibling)) { 1279 if (NeedGenerateForm(pTemplateChild, true)) { 1280 XFA_NodeMerge_CloneOrMergeContainer( 1281 pDocument, pExistingNode, pTemplateChild, bRecursive, nullptr); 1282 } 1283 } 1284 } 1285 pExistingNode->SetFlag(XFA_NodeFlag_Initialized, true); 1286 return pExistingNode; 1287 } 1288 1289 CXFA_Node* pNewNode = pTemplateNode->CloneTemplateToForm(false); 1290 pFormParent->InsertChild(pNewNode, nullptr); 1291 if (bRecursive) { 1292 for (CXFA_Node* pTemplateChild = 1293 pTemplateNode->GetNodeItem(XFA_NODEITEM_FirstChild); 1294 pTemplateChild; pTemplateChild = pTemplateChild->GetNodeItem( 1295 XFA_NODEITEM_NextSibling)) { 1296 if (NeedGenerateForm(pTemplateChild, true)) { 1297 CXFA_Node* pNewChild = pTemplateChild->CloneTemplateToForm(true); 1298 pNewNode->InsertChild(pNewChild, nullptr); 1299 } 1300 } 1301 } 1302 return pNewNode; 1303 } 1304 1305 CXFA_Node* XFA_DataMerge_FindDataScope(CXFA_Node* pParentFormNode) { 1306 for (CXFA_Node* pRootBoundNode = pParentFormNode; 1307 pRootBoundNode && pRootBoundNode->IsContainerNode(); 1308 pRootBoundNode = pRootBoundNode->GetNodeItem(XFA_NODEITEM_Parent)) { 1309 CXFA_Node* pDataScope = pRootBoundNode->GetBindData(); 1310 if (pDataScope) 1311 return pDataScope; 1312 } 1313 return ToNode( 1314 pParentFormNode->GetDocument()->GetXFAObject(XFA_HASHCODE_Data)); 1315 } 1316 1317 CXFA_Node* CXFA_Document::DataMerge_CopyContainer(CXFA_Node* pTemplateNode, 1318 CXFA_Node* pFormNode, 1319 CXFA_Node* pDataScope, 1320 bool bOneInstance, 1321 bool bDataMerge, 1322 bool bUpLevel) { 1323 switch (pTemplateNode->GetElementType()) { 1324 case XFA_Element::SubformSet: 1325 case XFA_Element::Subform: 1326 case XFA_Element::Area: 1327 case XFA_Element::PageArea: 1328 return CopyContainer_SubformSet(this, pTemplateNode, pFormNode, 1329 pDataScope, bOneInstance, bDataMerge); 1330 case XFA_Element::ExclGroup: 1331 case XFA_Element::Field: 1332 case XFA_Element::Draw: 1333 case XFA_Element::ContentArea: 1334 return CopyContainer_Field(this, pTemplateNode, pFormNode, pDataScope, 1335 bDataMerge, bUpLevel); 1336 case XFA_Element::PageSet: 1337 case XFA_Element::Variables: 1338 break; 1339 default: 1340 ASSERT(false); 1341 break; 1342 } 1343 return nullptr; 1344 } 1345 1346 void CXFA_Document::DataMerge_UpdateBindingRelations( 1347 CXFA_Node* pFormUpdateRoot) { 1348 CXFA_Node* pDataScope = XFA_DataMerge_FindDataScope( 1349 pFormUpdateRoot->GetNodeItem(XFA_NODEITEM_Parent)); 1350 if (!pDataScope) 1351 return; 1352 1353 UpdateBindingRelations(this, pFormUpdateRoot, pDataScope, false, false); 1354 UpdateBindingRelations(this, pFormUpdateRoot, pDataScope, true, false); 1355 } 1356 1357 CXFA_Node* CXFA_Document::GetNotBindNode(CXFA_ObjArray& arrayNodes) { 1358 for (int32_t i = 0; i < arrayNodes.GetSize(); i++) { 1359 CXFA_Node* pNode = arrayNodes[i]->AsNode(); 1360 if (pNode && !pNode->HasBindItem()) 1361 return pNode; 1362 } 1363 return nullptr; 1364 } 1365 1366 void CXFA_Document::DoDataMerge() { 1367 CXFA_Node* pDatasetsRoot = ToNode(GetXFAObject(XFA_HASHCODE_Datasets)); 1368 if (!pDatasetsRoot) { 1369 CFDE_XMLElement* pDatasetsXMLNode = new CFDE_XMLElement(L"xfa:datasets"); 1370 pDatasetsXMLNode->SetString(L"xmlns:xfa", 1371 L"http://www.xfa.org/schema/xfa-data/1.0/"); 1372 pDatasetsRoot = CreateNode(XFA_XDPPACKET_Datasets, XFA_Element::DataModel); 1373 pDatasetsRoot->SetCData(XFA_ATTRIBUTE_Name, L"datasets"); 1374 m_pRootNode->GetXMLMappingNode()->InsertChildNode(pDatasetsXMLNode); 1375 m_pRootNode->InsertChild(pDatasetsRoot); 1376 pDatasetsRoot->SetXMLMappingNode(pDatasetsXMLNode); 1377 } 1378 CXFA_Node *pDataRoot = nullptr, *pDDRoot = nullptr; 1379 CFX_WideString wsDatasetsURI; 1380 pDatasetsRoot->TryNamespace(wsDatasetsURI); 1381 for (CXFA_Node* pChildNode = 1382 pDatasetsRoot->GetNodeItem(XFA_NODEITEM_FirstChild); 1383 pChildNode; 1384 pChildNode = pChildNode->GetNodeItem(XFA_NODEITEM_NextSibling)) { 1385 if (pChildNode->GetElementType() != XFA_Element::DataGroup) 1386 continue; 1387 1388 CFX_WideString wsNamespaceURI; 1389 if (!pDDRoot && pChildNode->GetNameHash() == XFA_HASHCODE_DataDescription) { 1390 if (!pChildNode->TryNamespace(wsNamespaceURI)) 1391 continue; 1392 if (wsNamespaceURI == L"http://ns.adobe.com/data-description/") 1393 pDDRoot = pChildNode; 1394 } else if (!pDataRoot && pChildNode->GetNameHash() == XFA_HASHCODE_Data) { 1395 if (!pChildNode->TryNamespace(wsNamespaceURI)) 1396 continue; 1397 if (wsNamespaceURI == wsDatasetsURI) 1398 pDataRoot = pChildNode; 1399 } 1400 if (pDataRoot && pDDRoot) 1401 break; 1402 } 1403 1404 if (!pDataRoot) { 1405 CFDE_XMLElement* pDataRootXMLNode = new CFDE_XMLElement(L"xfa:data"); 1406 pDataRoot = CreateNode(XFA_XDPPACKET_Datasets, XFA_Element::DataGroup); 1407 pDataRoot->SetCData(XFA_ATTRIBUTE_Name, L"data"); 1408 pDataRoot->SetXMLMappingNode(pDataRootXMLNode); 1409 pDatasetsRoot->InsertChild(pDataRoot); 1410 } 1411 1412 CXFA_Node* pDataTopLevel = 1413 pDataRoot->GetFirstChildByClass(XFA_Element::DataGroup); 1414 uint32_t dwNameHash = pDataTopLevel ? pDataTopLevel->GetNameHash() : 0; 1415 CXFA_Node* pTemplateRoot = 1416 m_pRootNode->GetFirstChildByClass(XFA_Element::Template); 1417 if (!pTemplateRoot) 1418 return; 1419 1420 CXFA_Node* pTemplateChosen = 1421 dwNameHash != 0 ? pTemplateRoot->GetFirstChildByName(dwNameHash) 1422 : nullptr; 1423 if (!pTemplateChosen || 1424 pTemplateChosen->GetElementType() != XFA_Element::Subform) { 1425 pTemplateChosen = pTemplateRoot->GetFirstChildByClass(XFA_Element::Subform); 1426 } 1427 if (!pTemplateChosen) 1428 return; 1429 1430 CXFA_Node* pFormRoot = m_pRootNode->GetFirstChildByClass(XFA_Element::Form); 1431 bool bEmptyForm = false; 1432 if (!pFormRoot) { 1433 bEmptyForm = true; 1434 pFormRoot = CreateNode(XFA_XDPPACKET_Form, XFA_Element::Form); 1435 ASSERT(pFormRoot); 1436 pFormRoot->SetCData(XFA_ATTRIBUTE_Name, L"form"); 1437 m_pRootNode->InsertChild(pFormRoot, nullptr); 1438 } else { 1439 CXFA_NodeIteratorTemplate<CXFA_Node, CXFA_TraverseStrategy_XFANode> 1440 sIterator(pFormRoot); 1441 for (CXFA_Node* pNode = sIterator.MoveToNext(); pNode; 1442 pNode = sIterator.MoveToNext()) { 1443 pNode->SetFlag(XFA_NodeFlag_UnusedNode, true); 1444 } 1445 } 1446 1447 CXFA_Node* pSubformSetNode = XFA_NodeMerge_CloneOrMergeContainer( 1448 this, pFormRoot, pTemplateChosen, false, nullptr); 1449 ASSERT(pSubformSetNode); 1450 if (!pDataTopLevel) { 1451 CFX_WideStringC wsFormName = pSubformSetNode->GetCData(XFA_ATTRIBUTE_Name); 1452 CFX_WideString wsDataTopLevelName(wsFormName.IsEmpty() ? L"form" 1453 : wsFormName); 1454 CFDE_XMLElement* pDataTopLevelXMLNode = 1455 new CFDE_XMLElement(wsDataTopLevelName); 1456 1457 pDataTopLevel = CreateNode(XFA_XDPPACKET_Datasets, XFA_Element::DataGroup); 1458 pDataTopLevel->SetCData(XFA_ATTRIBUTE_Name, wsDataTopLevelName); 1459 pDataTopLevel->SetXMLMappingNode(pDataTopLevelXMLNode); 1460 CXFA_Node* pBeforeNode = pDataRoot->GetNodeItem(XFA_NODEITEM_FirstChild); 1461 pDataRoot->InsertChild(pDataTopLevel, pBeforeNode); 1462 } 1463 1464 ASSERT(pDataTopLevel); 1465 CreateDataBinding(pSubformSetNode, pDataTopLevel, true); 1466 for (CXFA_Node* pTemplateChild = 1467 pTemplateChosen->GetNodeItem(XFA_NODEITEM_FirstChild); 1468 pTemplateChild; 1469 pTemplateChild = pTemplateChild->GetNodeItem(XFA_NODEITEM_NextSibling)) { 1470 if (NeedGenerateForm(pTemplateChild, true)) { 1471 XFA_NodeMerge_CloneOrMergeContainer(this, pSubformSetNode, pTemplateChild, 1472 true, nullptr); 1473 } else if (pTemplateChild->IsContainerNode()) { 1474 DataMerge_CopyContainer(pTemplateChild, pSubformSetNode, pDataTopLevel, 1475 false, true, true); 1476 } 1477 } 1478 if (pDDRoot) 1479 UpdateDataRelation(pDataRoot, pDDRoot); 1480 1481 DataMerge_UpdateBindingRelations(pSubformSetNode); 1482 CXFA_Node* pPageSetNode = 1483 pSubformSetNode->GetFirstChildByClass(XFA_Element::PageSet); 1484 while (pPageSetNode) { 1485 m_pPendingPageSet.Add(pPageSetNode); 1486 CXFA_Node* pNextPageSetNode = 1487 pPageSetNode->GetNextSameClassSibling(XFA_Element::PageSet); 1488 pSubformSetNode->RemoveChild(pPageSetNode); 1489 pPageSetNode = pNextPageSetNode; 1490 } 1491 1492 if (bEmptyForm) 1493 return; 1494 1495 CXFA_NodeIteratorTemplate<CXFA_Node, CXFA_TraverseStrategy_XFANode> sIterator( 1496 pFormRoot); 1497 CXFA_Node* pNode = sIterator.MoveToNext(); 1498 while (pNode) { 1499 if (pNode->IsUnusedNode()) { 1500 if (pNode->IsContainerNode() || 1501 pNode->GetElementType() == XFA_Element::InstanceManager) { 1502 CXFA_Node* pNext = sIterator.SkipChildrenAndMoveToNext(); 1503 pNode->GetNodeItem(XFA_NODEITEM_Parent)->RemoveChild(pNode); 1504 pNode = pNext; 1505 } else { 1506 pNode->ClearFlag(XFA_NodeFlag_UnusedNode); 1507 pNode->SetFlag(XFA_NodeFlag_Initialized, true); 1508 pNode = sIterator.MoveToNext(); 1509 } 1510 } else { 1511 pNode->SetFlag(XFA_NodeFlag_Initialized, true); 1512 pNode = sIterator.MoveToNext(); 1513 } 1514 } 1515 } 1516 1517 void CXFA_Document::DoDataRemerge(bool bDoDataMerge) { 1518 CXFA_Node* pFormRoot = ToNode(GetXFAObject(XFA_HASHCODE_Form)); 1519 if (pFormRoot) { 1520 while (CXFA_Node* pNode = pFormRoot->GetNodeItem(XFA_NODEITEM_FirstChild)) 1521 pFormRoot->RemoveChild(pNode); 1522 pFormRoot->SetObject(XFA_ATTRIBUTE_BindingNode, nullptr); 1523 } 1524 m_rgGlobalBinding.clear(); 1525 if (bDoDataMerge) 1526 DoDataMerge(); 1527 1528 CXFA_LayoutProcessor* pLayoutProcessor = GetLayoutProcessor(); 1529 pLayoutProcessor->SetForceReLayout(true); 1530 } 1531