diff --git a/setup/modelfactory.class.inc.php b/setup/modelfactory.class.inc.php
index 53170ae13..e412a1abf 100644
--- a/setup/modelfactory.class.inc.php
+++ b/setup/modelfactory.class.inc.php
@@ -28,6 +28,70 @@ require_once(APPROOT.'setup/moduleinstaller.class.inc.php');
require_once(APPROOT.'setup/itopdesignformat.class.inc.php');
require_once(APPROOT.'core/designdocument.class.inc.php');
+/**
+ * Special exception type thrown when the XML stacking fails
+ *
+ */
+class MFException extends Exception
+{
+ /**
+ * @var integer
+ */
+ protected $iSourceLineNumber;
+ /**
+ * @var string
+ */
+ protected $sXPath;
+ /**
+ * @var string
+ */
+ protected $sExtraInfo;
+
+ const COULD_NOT_BE_ADDED = 1;
+ const COULD_NOT_BE_DELETED = 2;
+ const COULD_NOT_BE_MODIFIED_NOT_FOUND = 3;
+ const COULD_NOT_BE_MODIFIED_ALREADY_DELETED = 4;
+ const INVALID_DELTA = 5;
+ const ALREADY_DELETED = 6;
+ const NOT_FOUND = 7;
+
+
+ public function __construct ($message = null, $code = null, $iSourceLineNumber = 0, $sXPath = '', $sExtraInfo = '', $previous = null)
+ {
+ parent::__construct($message, $code, $previous);
+ $this->iSourceLineNumber = $iSourceLineNumber;
+ $this->sXPath = $sXPath;
+ $this->sExtraInfo = $sExtraInfo;
+ }
+
+ /**
+ * Get the source line number where the problem happened
+ * @return number
+ */
+ public function GetSourceLineNumber()
+ {
+ return $this->iSourceLineNumber;
+ }
+
+ /**
+ * Get the XPath in the whole document where the problem happened
+ * @return string
+ */
+ public function GetXPath()
+ {
+ return $this->sXPath;
+ }
+
+ /**
+ * Get some extra info (depending on the exception's code), like the invalid value for the _delta attribute
+ * @return string
+ */
+ public function GetExtraInfo()
+ {
+ return $this->sExtraInfo;
+ }
+}
+
/**
* ModelFactoryModule: the representation of a Module (i.e. element that can be selected during the setup)
* @package ModelFactory
@@ -408,7 +472,9 @@ class ModelFactory
{
echo "Dumping target doc - looking for '$sParentId'
\n";
$this->oDOMDocument->firstChild->Dump();
- throw new Exception(MFDocument::GetItopNodePath($oSourceNode).' at line '.$oSourceNode->getLineNo().": could not find parent with id '$sParentId'");
+ $sPath = MFDocument::GetItopNodePath($oSourceNode);
+ $iLine = $oSourceNode->getLineNo();
+ throw new MFException($sPath.' at line '.$iLine.": could not be found", MFException::PARENT_NOT_FOUND, $iLine, $sPath, $sParentId);
}
}
else
@@ -424,7 +490,10 @@ class ModelFactory
{
echo "Dumping target doc - looking for '".$oSourceNode->getAttribute('id')."'
\n";
$this->oDOMDocument->firstChild->Dump();
- throw new Exception(MFDocument::GetItopNodePath($oSourceNode).' at line '.$oSourceNode->getLineNo().": could not be found");
+ $sPath = MFDocument::GetItopNodePath($oSourceNode);
+ $iLine = $oSourceNode->getLineNo();
+ throw new MFException($sPath.' at line '.$iLine.": could not be found", MFException::NOT_FOUND, $iLine, $sPath);
+
}
}
else
@@ -509,19 +578,23 @@ class ModelFactory
case 'delete':
$oTargetNode = $oTargetParentNode->_FindChildNode($oSourceNode);
+ $sPath = MFDocument::GetItopNodePath($oSourceNode);
+ $iLine = $oSourceNode->getLineNo();
if ($oTargetNode == null)
{
- throw new Exception(MFDocument::GetItopNodePath($oSourceNode).' at line '.$oSourceNode->getLineNo().": could not be deleted (not found)");
+ throw new MFException($sPath.' at line '.$iLine.": could not be deleted (not found)", MFException::COULD_NOT_BE_DELETED, $iLine, $sPath);
}
if ($oTargetNode->getAttribute('_alteration') == 'removed')
{
- throw new Exception(MFDocument::GetItopNodePath($oSourceNode).' at line '.$oSourceNode->getLineNo().": could not be deleted (already marked as deleted)");
+ throw new MFException($sPath.' at line '.$iLine.": could not be deleted (already marked as deleted)", MFException::ALREADY_DELETED, $iLine, $sPath);
}
$oTargetNode->Delete();
break;
default:
- throw new Exception(MFDocument::GetItopNodePath($oSourceNode).' at line '.$oSourceNode->getLineNo().": unexpected value for attribute _delta: '".$sDeltaSpec."'");
+ $sPath = MFDocument::GetItopNodePath($oSourceNode);
+ $iLine = $oSourceNode->getLineNo();
+ throw new MFException($sPath.' at line '.$iLine.": unexpected value for attribute _delta: '".$sDeltaSpec."'", MFException::INVALID_DELTA, $iLine, $sPath, $sDeltaSpec);
}
if ($oTargetNode)
@@ -1728,7 +1801,9 @@ class MFElement extends Combodo\iTop\DesignElement
{
if ($oExisting->getAttribute('_alteration') != 'removed')
{
- throw new Exception(MFDocument::GetItopNodePath($oNode).' at line '.$oNode->getLineNo().": could not be added (already exists)");
+ $sPath = MFDocument::GetItopNodePath($oNode);
+ $iLine = $oNode->getLineNo();
+ throw new MFException($sPath.' at line '.$iLine.": could not be added (already exists)", MFException::COULD_NOT_BE_ADDED, $iLine, $sPath);
}
$oExisting->ReplaceWith($oNode);
$sFlag = 'replaced';
@@ -1757,14 +1832,17 @@ class MFElement extends Combodo\iTop\DesignElement
$oExisting = $this->_FindChildNode($oNode, $sSearchId);
if (!$oExisting)
{
- $sSourceNode = MFDocument::GetItopNodePath($this)."/".$oNode->tagName.(is_null($sSearchId) ? '' : "[$sSearchId]").' at line '.$this->getLineNo();
- throw new Exception($sSourceNode.": could not be modified (not found)");
+ $sPath = MFDocument::GetItopNodePath($this)."/".$oNode->tagName.(empty($sSearchId) ? '' : "[$sSearchId]");
+ $iLine = $oNode->getLineNo();
+ throw new MFException($sPath." at line $iLine: could not be modified (not found)", MFException::COULD_NOT_BE_MODIFIED_NOT_FOUND, $sPath, $iLine);
}
$sPrevFlag = $oExisting->getAttribute('_alteration');
if ($sPrevFlag == 'removed')
{
+ $sPath = MFDocument::GetItopNodePath($this)."/".$oNode->tagName.(empty($sSearchId) ? '' : "[$sSearchId]");
+ $iLine = $oNode->getLineNo();
$sSourceNode = MFDocument::GetItopNodePath($this)."/".$oNode->tagName.(is_null($sSearchId) ? '' : "[$sSearchId]").' at line '.$this->getLineNo();
- throw new Exception($sSourceNode.": could not be modified (marked as deleted)");
+ throw new MFException($sPath." at line $iLine: could not be modified (marked as deleted)", MFException::COULD_NOT_BE_MODIFIED_ALREADY_DELETED, $sPath, $iLine);
}
$oExisting->ReplaceWith($oNode);
if (!$this->IsInDefinition())
@@ -2080,7 +2158,7 @@ class MFDocument extends \Combodo\iTop\DesignDocument
$oRootNode->setAttribute('version', ITOP_DESIGN_LATEST_VERSION);
$this->appendChild($oRootNode);
}
- return parent::saveXML();
+ return parent::saveXML($node);
}
/**