From 86d2a3424d0471b29e283819250aebb61907a751 Mon Sep 17 00:00:00 2001 From: odain Date: Wed, 18 Jun 2025 15:45:29 +0200 Subject: [PATCH] =?UTF-8?q?N=C2=B08306=20-=20Wrong=20line=20number=20error?= =?UTF-8?q?=20if=20XML=20is=20over=2065535=20lines?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- setup/modelfactory.class.inc.php | 86 ++++++++++++++++---------------- 1 file changed, 43 insertions(+), 43 deletions(-) diff --git a/setup/modelfactory.class.inc.php b/setup/modelfactory.class.inc.php index 21b49ec58..771d6f2f7 100644 --- a/setup/modelfactory.class.inc.php +++ b/setup/modelfactory.class.inc.php @@ -749,13 +749,37 @@ class ModelFactory case 'define_if_not_exists': /** @var \MFElement $oParentNode */ $oParentNode = $oSubClassNode->parentNode; - $iLine = ModelFactory::GetXMLLineNumber($oParentNode); - $sItopNodePath = DesignDocument::GetItopNodePath($oParentNode); - throw new MFException("$sItopNodePath at line $iLine: _delta=\"$sParentDeltaSpec\" not supported for classes in hierarchy", - MFException::NOT_FOUND, $iLine, $sItopNodePath); + self::ThrowMFException("_delta=\"$sParentDeltaSpec\" not supported for classes in hierarchy", MFException::NOT_FOUND, $oParentNode); } } + /** + * @covers N°8306: try to print correct XML line number + * @param string $sMsg + * @param $code + * @param $oNode + * @param $sExtraInfo + * @param $sItopNodePath + * + * @return mixed + * @throws \MFException + */ + public static function ThrowMFException(string $sMsg, $code, $oNode, $sExtraInfo='', $sItopNodePath=null, $oParentFallbackNode=null) + { + $iLine = ModelFactory::GetXMLLineNumber($oNode); + if ($iLine==0 && ! is_null($oParentFallbackNode)){ + $iLine = ModelFactory::GetXMLLineNumber($oParentFallbackNode); + } + + if (is_null($sItopNodePath)){ + $sItopNodePath = DesignDocument::GetItopNodePath($oNode); + } + + $oMFException = new MFException("$sItopNodePath at line $iLine: $sMsg", $code, $iLine, $sItopNodePath, $sExtraInfo); + \IssueLog::Debug(__METHOD__, null, [$oMFException->getMessage(), $oMFException->getTraceAsString()]); + throw $oMFException; + } + /** * @param DesignElement $oSourceNode Delta node * @param \MFDocument $oTargetDocument Datamodel @@ -808,10 +832,7 @@ class ModelFactory // Move class after new parent class (before its next sibling) $oNodeForTargetParent = $oTargetDocument->GetNodes("/itop_design/classes/class[@id=\"$sParentClassName\"]")->item(0); if (is_null($oNodeForTargetParent)) { - $iLine = ModelFactory::GetXMLLineNumber($oSourceParentClassNode); - $sItopNodePath = DesignDocument::GetItopNodePath($oSourceParentClassNode); - throw new MFException($sItopNodePath." at line $iLine: invalid parent class '$sParentClassName'", - MFException::NOT_FOUND, $iLine, $sItopNodePath); + self::ThrowMFException("invalid parent class '$sParentClassName'", MFException::NOT_FOUND, $oSourceParentClassNode); } $oNextParentSibling = $oNodeForTargetParent->nextSibling; if ($oNextParentSibling) { @@ -839,20 +860,14 @@ class ModelFactory if (!$oTargetNode || $oTargetNode->IsRemoved()) { // The node does not exist or is marked as removed if ($bMustExist) { - $iLine = ModelFactory::GetXMLLineNumber($oSourceNode); - $sItopNodePath = DesignDocument::GetItopNodePath($oSourceNode); - throw new MFException($sItopNodePath.' at line '.$iLine.': could not be found or marked as removed', - MFException::NOT_FOUND, $iLine, $sItopNodePath); + self::ThrowMFException("could not be found or marked as removed", MFException::NOT_FOUND, $oSourceNode); } if ($bIfExists) { // Do not continue deeper $oTargetNode = null; } else { if (!$bSpecifiedMerge && $sMode === self::LOAD_DELTA_MODE_STRICT && ($sSearchId !== '' || is_null($oSourceNode->GetFirstElementChild()))) { - $iLine = ModelFactory::GetXMLLineNumber($oSourceNode); - $sItopNodePath = DesignDocument::GetItopNodePath($oSourceNode); - throw new MFException($sItopNodePath.' at line '.$iLine.': could not be found or marked as removed (strict mode)', - MFException::NOT_FOUND, $iLine, $sItopNodePath, 'strict mode'); + self::ThrowMFException("could not be found or marked as removed (strict mode)", MFException::NOT_FOUND, $oSourceNode, 'strict mode'); } // Ignore renaming non-existant node @@ -901,10 +916,7 @@ class ModelFactory if (is_null($oSourceNode->GetFirstElementChild()) && $oTargetParentNode instanceof MFElement) { // Leaf node if ($sMode === self::LOAD_DELTA_MODE_STRICT && !$oSourceNode->hasAttribute('_rename_from') && trim($oSourceNode->GetText('')) !== '') { - $iLine = ModelFactory::GetXMLLineNumber($oSourceNode); - $sItopNodePath = DesignDocument::GetItopNodePath($oSourceNode); - throw new MFException($sItopNodePath.' at line '.$iLine.': cannot be modified without _delta flag (strict mode)', - MFException::AMBIGUOUS_LEAF, $iLine, $sItopNodePath, 'strict mode'); + self::ThrowMFException("cannot be modified without _delta flag (strict mode)", MFException::AMBIGUOUS_LEAF, $oSourceNode, 'strict mode'); } else { // Lax mode: same as redefine // Replace the existing node by the given node - copy child nodes as well @@ -912,7 +924,7 @@ class ModelFactory if (trim($oSourceNode->GetText('')) !== '') { $oTargetNode = $oTargetDocument->importNode($oSourceNode, true); $sSearchId = $oSourceNode->hasAttribute('_rename_from') ? $oSourceNode->getAttribute('_rename_from') : $oSourceNode->getAttribute('id'); - $oTargetParentNode->RedefineChildNode($oTargetNode, $sSearchId); + $oTargetParentNode->RedefineChildNode($oTargetNode, $sSearchId, $oSourceNode); } } } else { @@ -956,7 +968,7 @@ class ModelFactory // Replace the existing node by the given node - copy child nodes as well /** @var \MFElement $oTargetNode */ $oTargetNode = $oTargetDocument->importNode($oSourceNode, true); - $oTargetParentNode->RedefineChildNode($oTargetNode, $sSearchId); + $oTargetParentNode->RedefineChildNode($oTargetNode, $sSearchId, $oSourceNode); break; case 'delete_if_exists': @@ -976,25 +988,18 @@ class ModelFactory case 'delete': /** @var \MFElement $oTargetNode */ $oTargetNode = $oTargetParentNode->_FindChildNode($oSourceNode, $sSearchId); - $sPath = MFDocument::GetItopNodePath($oSourceNode); - $iLine = $this->GetXMLLineNumber($oSourceNode); if ($oTargetNode == null) { - throw new MFException($sPath.' at line '.$iLine.": could not be deleted (not found)", MFException::COULD_NOT_BE_DELETED, - $iLine, $sPath); + self::ThrowMFException("could not be deleted (not found)", MFException::COULD_NOT_BE_DELETED, $oSourceNode); } if ($oTargetNode->IsRemoved()) { - throw new MFException($sPath.' at line '.$iLine.": could not be deleted (already marked as deleted)", - MFException::ALREADY_DELETED, $iLine, $sPath); + self::ThrowMFException("could not be deleted (already marked as deleted)", MFException::ALREADY_DELETED, $oSourceNode); } $oTargetNode->Delete(); break; default: - $sPath = MFDocument::GetItopNodePath($oSourceNode); - $iLine = $this->GetXMLLineNumber($oSourceNode); - throw new MFException($sPath.' at line '.$iLine.": unexpected value for attribute _delta: '".$sDeltaSpec."'", - MFException::INVALID_DELTA, $iLine, $sPath, $sDeltaSpec); + self::ThrowMFException("unexpected value for attribute _delta: '".$sDeltaSpec."'", MFException::INVALID_DELTA, $oSourceNode, $sDeltaSpec); } if ($oTargetNode && $oTargetNode->parentNode) { @@ -2201,14 +2206,12 @@ class MFElement extends Combodo\iTop\DesignElement if ($oExisting) { if (!$oExisting->IsRemoved()) { - $sPath = MFDocument::GetItopNodePath($oNode); - $iLine = ModelFactory::GetXMLLineNumber($oNode); $sExistingPath = MFDocument::GetItopNodePath($oExisting).' created_in: ['.$oExisting->getAttribute('_created_in').']'; $iExistingLine = ModelFactory::GetXMLLineNumber($oExisting); $sExceptionMessage = <<ReplaceWithSingleNode($oNode); $sFlag = 'replaced'; @@ -2229,13 +2232,14 @@ EOF; * * @param MFElement $oNode The node (including all subnodes) to set * @param string|null $sSearchId + * @param mixed $oParentFallbackNode: provided to print accurate line number in case $oNode line is 0 * * @return void * * @throws MFException * @throws \Exception */ - public function RedefineChildNode(MFElement $oNode, $sSearchId = null) + public function RedefineChildNode(MFElement $oNode, $sSearchId = null, $oParentFallbackNode=null) { // First: cleanup any flag behind the new node, and eventually add trace data $oNode->ApplyChanges(); @@ -2245,17 +2249,13 @@ EOF; if (!$oExisting) { $sPath = MFDocument::GetItopNodePath($this)."/".$oNode->tagName.(empty($sSearchId) ? '' : "[$sSearchId]"); - $iLine = ModelFactory::GetXMLLineNumber($oNode); - throw new MFException($sPath." at line $iLine: could not be modified (not found)", MFException::COULD_NOT_BE_MODIFIED_NOT_FOUND, - $sPath, $iLine); + ModelFactoryEx::ThrowMFException('could not be modified (not found)', MFException::COULD_NOT_BE_MODIFIED_NOT_FOUND, $oNode, '', $sPath, $oParentFallbackNode); } $sPrevFlag = $oExisting->GetAlteration(); $sOldId = $oExisting->getAttribute('_old_id'); if ($oExisting->IsRemoved()) { $sPath = MFDocument::GetItopNodePath($this)."/".$oNode->tagName.(empty($sSearchId) ? '' : "[$sSearchId]"); - $iLine = ModelFactory::GetXMLLineNumber($oNode); - throw new MFException($sPath." at line $iLine: could not be modified (marked as deleted)", - MFException::COULD_NOT_BE_MODIFIED_ALREADY_DELETED, $sPath, $iLine); + ModelFactoryEx::ThrowMFException('could not be modified (marked as deleted)', MFException::COULD_NOT_BE_MODIFIED_ALREADY_DELETED, $oNode, '', $sPath, $oParentFallbackNode); } $oExisting->ReplaceWithSingleNode($oNode); if (!$this->IsInDefinition()) {