Bladeren bron

XML Modelization of the relations: reworked toward an asymetric definition (downstream: A impacts B, upstream: B depends on A)
- The queries are developped at runtime (cache)
- More complex algorithm to take into account the legacy type of specification (GetRelationQueries)
- New dictionary naming convention (preserving backward compatibility): "VerbUp" to be replaced by "DownStream
- Temporary hacks to preserve the relation 'depends on', until we have a new GUI
- Special handling for the relation LogicalVolume impacts VirtualDevice which had to be implemented in the bridge module
- Improved the backward compatibility by leaving legacy methods GetRelationQueries returning an empty definition, allowing for an eventual XML redefinition

git-svn-id: http://svn.code.sf.net/p/itop/code/trunk@3542 a333f486-631f-4898-b8df-5754b55c2be0

romainq 10 jaren geleden
bovenliggende
commit
8ecee4985a
24 gewijzigde bestanden met toevoegingen van 2064 en 1654 verwijderingen
  1. 13 3
      core/dbobject.class.php
  2. 236 44
      core/metamodel.class.php
  3. 11 0
      datamodels/2.x/itop-bridge-virtualization-storage/datamodel.itop-bridge-virtualization-storage.xml
  4. 2 0
      datamodels/2.x/itop-bridge-virtualization-storage/module.itop-bridge-virtualization-storage.php
  5. 4 4
      datamodels/2.x/itop-config-mgmt/da.dict.itop-config-mgmt.php
  6. 168 62
      datamodels/2.x/itop-config-mgmt/datamodel.itop-config-mgmt.xml
  7. 4 4
      datamodels/2.x/itop-config-mgmt/de.dict.itop-config-mgmt.php
  8. 4 4
      datamodels/2.x/itop-config-mgmt/en.dict.itop-config-mgmt.php
  9. 4 4
      datamodels/2.x/itop-config-mgmt/es_cr.dict.itop-config-mgmt.php
  10. 4 4
      datamodels/2.x/itop-config-mgmt/fr.dict.itop-config-mgmt.php
  11. 4 4
      datamodels/2.x/itop-config-mgmt/hu.dict.itop-config-mgmt.php
  12. 4 4
      datamodels/2.x/itop-config-mgmt/it.dict.itop-config-mgmt.php
  13. 4 4
      datamodels/2.x/itop-config-mgmt/ja.dict.itop-config-mgmt.php
  14. 4 4
      datamodels/2.x/itop-config-mgmt/nl.dict.itop-config-mgmt.php
  15. 4 4
      datamodels/2.x/itop-config-mgmt/pt_br.dict.itop-config-mgmt.php
  16. 4 4
      datamodels/2.x/itop-config-mgmt/ru.dict.itop-config-mgmt.php
  17. 4 4
      datamodels/2.x/itop-config-mgmt/tr.dict.itop-config-mgmt.php
  18. 4 4
      datamodels/2.x/itop-config-mgmt/zh.dict.itop-config-mgmt.php
  19. 16 11
      datamodels/2.x/itop-datacenter-mgmt/datamodel.itop-datacenter-mgmt.xml
  20. 84 25
      datamodels/2.x/itop-storage-mgmt/datamodel.itop-storage-mgmt.xml
  21. 48 25
      datamodels/2.x/itop-virtualization-mgmt/datamodel.itop-virtualization-mgmt.xml
  22. 1417 1417
      dictionaries/da.dictionary.itop.core.php
  23. 3 2
      pages/schema.php
  24. 14 13
      setup/compiler.class.inc.php

+ 13 - 3
core/dbobject.class.php

@@ -2547,10 +2547,20 @@ abstract class DBObject implements iDisplay
 
 	public function GetRelatedObjects($sRelCode, $iMaxDepth = 99, &$aResults = array())
 	{
-		foreach (MetaModel::EnumRelationQueries(get_class($this), $sRelCode) as $sDummy => $aQueryInfo)
+		// Temporary patch: until the impact analysis GUI gets rewritten,
+		// let's consider that "depends on" is equivalent to "impacts/up"
+		// The current patch has been implemented in DBObject and MetaModel
+		$sHackedRelCode = $sRelCode;
+		$bDown = true;
+		if ($sRelCode == 'depends on')
 		{
-			MetaModel::DbgTrace("object=".$this->GetKey().", depth=$iMaxDepth, rel=".$aQueryInfo["sQuery"]);
-			$sQuery = $aQueryInfo["sQuery"];
+			$sHackedRelCode = 'impacts';
+			$bDown = false;
+		}
+		foreach (MetaModel::EnumRelationQueries(get_class($this), $sHackedRelCode, $bDown) as $sDummy => $aQueryInfo)
+		{
+			MetaModel::DbgTrace("object=".$this->GetKey().", depth=$iMaxDepth, rel=".$aQueryInfo['sQueryDown']);
+			$sQuery = $bDown ? $aQueryInfo['sQueryDown'] : $aQueryInfo['sQueryUp'];
 			//$bPropagate = $aQueryInfo["bPropagate"];
 			//$iDepth = $bPropagate ? $iMaxDepth - 1 : 0;
 			$iDepth = $iMaxDepth - 1;

+ 236 - 44
core/metamodel.class.php

@@ -1112,15 +1112,35 @@ abstract class MetaModel
 			$aClassRelations = array();
 			foreach($aResult as $sRelCode)
 			{	
-				$aQueries = self::EnumRelationQueries($sClass, $sRelCode);
-				if (count($aQueries) > 0)
+				$aQueriesDown = self::EnumRelationQueries($sClass, $sRelCode);
+				if (count($aQueriesDown) > 0)
 				{
 					$aClassRelations[] = $sRelCode;
 				}
+				// Temporary patch: until the impact analysis GUI gets rewritten,
+				// let's consider that "depends on" is equivalent to "impacts/up"
+				// The current patch has been implemented in DBObject and MetaModel
+				if ($sRelCode == 'impacts')
+				{
+					$aQueriesUp = self::EnumRelationQueries($sClass, 'impacts', false);
+					if (count($aQueriesUp) > 0)
+					{
+						$aClassRelations[] = 'depends on';
+					}
+				}
 			}
-			return $aClassRelations;
+
+ 			return $aClassRelations;
 		}
-		
+
+		// Temporary patch: until the impact analysis GUI gets rewritten,
+		// let's consider that "depends on" is equivalent to "impacts/up"
+		// The current patch has been implemented in DBObject and MetaModel
+		if (in_array('impacts', $aResult))
+		{
+			$aResult[] = 'depends on';
+		}
+
 		return $aResult;
 	}
 
@@ -1131,70 +1151,242 @@ abstract class MetaModel
 
 	final static public function GetRelationLabel($sRelCode)
 	{
-		return Dict::S("Relation:$sRelCode/VerbUp");
+		// The legacy convention is confusing with regard to the way we have conceptualized the relations:
+		// In the former representation, the main stream was named after "up"
+		// Now, the relation from A to B says that something is transmitted from A to B, thus going DOWNstream as described in a petri net.
+		$sKey = "Relation:$sRelCode/DownStream";
+		$sLegacy = Dict::S("Relation:$sRelCode/VerbUp", $sKey);
+		$sRet = Dict::S($sKey, $sLegacy);
+		return $sRet;
 	}
 
-	public static function EnumRelationQueries($sClass, $sRelCode)
-	{
-		MyHelpers::CheckKeyInArray('relation code', $sRelCode, self::$m_aRelationInfos);
-
-		$aNeighbours = call_user_func_array(array($sClass, 'GetRelationQueriesEx'), array($sRelCode));
 
-		// Translate attributes into queries (new style of spec only)
-		foreach($aNeighbours as $trash => &$aNeighbourData)
+	protected static function ComputeRelationQueries($sRelCode)
+	{
+		$bHasLegacy = false;
+		$aQueries = array();
+		foreach (self::GetClasses() as $sClass)
 		{
-			try
+			$aQueries[$sClass]['down'] = array();
+			if (!array_key_exists('up', $aQueries[$sClass]))
+			{
+				$aQueries[$sClass]['up'] = array();
+			}
+
+			$aNeighboursDown = call_user_func_array(array($sClass, 'GetRelationQueriesEx'), array($sRelCode));
+	
+			// Translate attributes into queries (new style of spec only)
+			foreach($aNeighboursDown as $sNeighbourId => $aNeighbourData)
 			{
-				if (strlen($aNeighbourData['sQuery']) == 0)
+				$aNeighbourData['sFromClass'] = $aNeighbourData['sDefinedInClass'];
+				try
 				{
-					$oAttDef = self::GetAttributeDef($sClass, $aNeighbourData['sAttribute']);
-					if ($oAttDef instanceof AttributeExternalKey)
+					if (strlen($aNeighbourData['sQueryDown']) == 0)
 					{
-						$sTargetClass = $oAttDef->GetTargetClass();
-						$aNeighbourData['sQuery'] = 'SELECT '.$sTargetClass.' AS o WHERE o.id = :this->'.$aNeighbourData['sAttribute'];
-					}
-					elseif ($oAttDef instanceof AttributeLinkedSet)
-					{
-						$sLinkedClass = $oAttDef->GetLinkedClass();
-						$sExtKeyToMe = $oAttDef->GetExtKeyToMe();
-						if ($oAttDef->IsIndirect())
+						$oAttDef = self::GetAttributeDef($sClass, $aNeighbourData['sAttribute']);
+						if ($oAttDef instanceof AttributeExternalKey)
 						{
-							$sExtKeyToRemote = $oAttDef->GetExtKeyToRemote();
-							$oRemoteAttDef = self::GetAttributeDef($sLinkedClass, $sExtKeyToRemote);
-							$sRemoteClass = $oRemoteAttDef->GetTargetClass();
-	
-							$aNeighbourData['sQuery'] = "SELECT $sRemoteClass AS o JOIN $sLinkedClass AS lnk ON lnk.$sExtKeyToRemote = o.id WHERE lnk.$sExtKeyToMe = :this->id";
+							$sTargetClass = $oAttDef->GetTargetClass();
+							$aNeighbourData['sToClass'] = $sTargetClass;
+							$aNeighbourData['sQueryDown'] = 'SELECT '.$sTargetClass.' AS o WHERE o.id = :this->'.$aNeighbourData['sAttribute'];
+							$aNeighbourData['sQueryUp'] = 'SELECT '.$sClass.' AS o WHERE o.'.$aNeighbourData['sAttribute'].' = :this->id';
+						}
+						elseif ($oAttDef instanceof AttributeLinkedSet)
+						{
+							$sLinkedClass = $oAttDef->GetLinkedClass();
+							$sExtKeyToMe = $oAttDef->GetExtKeyToMe();
+							if ($oAttDef->IsIndirect())
+							{
+								$sExtKeyToRemote = $oAttDef->GetExtKeyToRemote();
+								$oRemoteAttDef = self::GetAttributeDef($sLinkedClass, $sExtKeyToRemote);
+								$sRemoteClass = $oRemoteAttDef->GetTargetClass();
+		
+								$aNeighbourData['sToClass'] = $sRemoteClass;
+								$aNeighbourData['sQueryDown'] = "SELECT $sRemoteClass AS o JOIN $sLinkedClass AS lnk ON lnk.$sExtKeyToRemote = o.id WHERE lnk.$sExtKeyToMe = :this->id";
+								$aNeighbourData['sQueryUp'] = "SELECT $sClass AS o JOIN $sLinkedClass AS lnk ON lnk.$sExtKeyToMe = o.id WHERE lnk.$sExtKeyToRemote = :this->id";
+							}
+							else
+							{
+								$aNeighbourData['sToClass'] = $sLinkedClass;
+								$aNeighbourData['sQueryDown'] = "SELECT $sLinkedClass AS o WHERE o.$sExtKeyToMe = :this->id";
+								$aNeighbourData['sQueryUp'] = "SELECT $sClass AS o WHERE o.id = :this->$sExtKeyToMe";
+							}
 						}
 						else
 						{
-							$aNeighbourData['sQuery'] = "SELECT $sLinkedClass AS o WHERE o.$sExtKeyToMe = :this->id";
+							throw new Exception("Unexpected attribute type for '{$aNeighbourData['sAttribute']}'. Expecting a link set or external key.");
 						}
 					}
 					else
 					{
-						throw new Exception("Unexpected attribute type for '{$aNeighbourData['sAttribute']}'. Expecting a link set or external key.");
+						$oSearch = DBObjectSearch::FromOQL($aNeighbourData['sQueryDown']);
+						$aNeighbourData['sToClass'] = $oSearch->GetClass();
+					}
+				}
+				catch (Exception $e)
+				{
+					throw new Exception("Wrong definition for the relation $sRelCode/{$aNeighbourData['sDefinedInClass']}/{$aNeighbourData['sNeighbour']}: ".$e->getMessage());
+				}
+
+				$sArrowId = $aNeighbourData['sDefinedInClass'].'_'.$sNeighbourId;
+				$aQueries[$sClass]['down'][$sArrowId] = $aNeighbourData;
+
+				// Compute the reverse index
+				if ($aNeighbourData['sDefinedInClass'] == $sClass)
+				{
+					$sFromClass = $aNeighbourData['sFromClass'];
+					$sToClass = $aNeighbourData['sToClass'];
+					foreach (self::EnumChildClasses($sToClass, ENUM_CHILD_CLASSES_ALL) as $sSubClass)
+					{
+						$aQueries[$sSubClass]['up'][$sArrowId] = $aNeighbourData;
 					}
 				}
 			}
-			catch (Exception $e)
+
+			// Read legacy definitions
+			// The up/down queries have to be reconcilied, which can only be done later when all the classes have been browsed
+			//
+			// The keys used to store a query (up or down) into the array are built differently between the modern and legacy made data:
+			// Modern way: aQueries[sClass]['up'|'down'][sArrowId], where sArrowId is made of the source class + neighbour id (XML def)
+			// Legacy way: aQueries[sClass]['up'|'down'][sRemoteClass]
+			// The modern way does allow for several arrows between two classes
+			// The legacy way aims at simplifying the transformation (reconciliation between up and down)
+			if ($sRelCode == 'impacts')
 			{
-				$sClassOfDefinition = $aNeighbourData['_legacy_'] ? $sClass.'(or a parent)::GetRelationQueries()' : $aNeighbourData['sDefinedInClass'];
-				throw new Exception("Wrong definition for the relation $sRelCode/$sClassOfDefinition/{$aNeighbourData['sNeighbour']}: ".$e->getMessage());
+				$sRevertCode = 'depends on';
+
+				$aLegacy = call_user_func_array(array($sClass, 'GetRelationQueries'), array($sRelCode));
+				foreach($aLegacy as $sId => $aLegacyEntry)
+				{
+					$bHasLegacy = true;
+					
+					$oFilter = DBObjectSearch::FromOQL($aLegacyEntry['sQuery']);
+					$sRemoteClass = $oFilter->GetClass();
+
+					// Determine wether the query is inherited from a parent or not
+					$bInherited = false;
+					foreach (self::EnumParentClasses($sClass) as $sParent)
+					{
+						if (!isset($aQueries[$sParent]['down'][$sRemoteClass])) continue;
+						if ($aLegacyEntry['sQuery'] == $aQueries[$sParent]['down'][$sRemoteClass]['sQueryDown'])
+						{
+							$bInherited = true;
+							$aQueries[$sClass]['down'][$sRemoteClass] = $aQueries[$sParent]['down'][$sRemoteClass];
+							break;
+						}
+					}
+
+					if (!$bInherited)
+					{
+						$aQueries[$sClass]['down'][$sRemoteClass] = array(
+							'_legacy_' => true,
+							'sDefinedInClass' => $sClass,
+							'sFromClass' => $sClass,
+							'sToClass' => $sRemoteClass,
+							'sQueryDown' => $aLegacyEntry['sQuery'],
+							'sNeighbour' => $sRemoteClass // Normalize the neighbour id
+						);
+					}
+				}
+
+				$aLegacy = call_user_func_array(array($sClass, 'GetRelationQueries'), array($sRevertCode));
+				foreach($aLegacy as $sId => $aLegacyEntry)
+				{
+					$bHasLegacy = true;
+
+					$oFilter = DBObjectSearch::FromOQL($aLegacyEntry['sQuery']);
+					$sRemoteClass = $oFilter->GetClass();
+
+					// Determine wether the query is inherited from a parent or not
+					$bInherited = false;
+					foreach (self::EnumParentClasses($sClass) as $sParent)
+					{
+						if (!isset($aQueries[$sParent]['up'][$sRemoteClass])) continue;
+						if ($aLegacyEntry['sQuery'] == $aQueries[$sParent]['up'][$sRemoteClass]['sQueryUp'])
+						{
+							$bInherited = true;
+							$aQueries[$sClass]['up'][$sRemoteClass] = $aQueries[$sParent]['up'][$sRemoteClass];
+							break;
+						}
+					}
+
+					if (!$bInherited)
+					{
+						$aQueries[$sClass]['up'][$sRemoteClass] = array(
+							'_legacy_' => true,
+							'sDefinedInClass' => $sRemoteClass,
+							'sFromClass' => $sRemoteClass,
+							'sToClass' => $sClass,
+							'sQueryUp' => $aLegacyEntry['sQuery'],
+							'sNeighbour' => $sClass// Normalize the neighbour id
+						);
+					}
+				}
+			}
+			else
+			{
+				// Cannot take the legacy system into account... simply ignore it
+			}
+		} // foreach class
+
+		// Perform the up/down reconciliation for the legacy definitions
+		if ($bHasLegacy)
+		{
+			foreach (self::GetClasses() as $sClass)
+			{
+				// Foreach "up" legacy query, update its "down" counterpart
+				if (isset($aQueries[$sClass]['up']))
+				{
+					foreach ($aQueries[$sClass]['up'] as $sNeighbourId => $aNeighbourData)
+					{
+						if (!$aNeighbourData['_legacy_']) continue; // Skip modern definitions
+
+						$sLocalClass = $aNeighbourData['sToClass'];
+						foreach (self::EnumChildClasses($aNeighbourData['sFromClass'], ENUM_CHILD_CLASSES_ALL) as $sRemoteClass)
+						{
+							if (isset($aQueries[$sRemoteClass]['down'][$sLocalClass]))
+							{
+								$aQueries[$sRemoteClass]['down'][$sLocalClass]['sQueryUp'] = $aNeighbourData['sQueryUp'];
+							}
+							else
+							{
+								throw new Exception("Legacy definition of the relation '$sRelCode/$sRevertCode', defined on $sLocalClass (relation: $sRevertCode, inherited to $sClass), missing the counterpart query on class $sRemoteClass ($sRelCode)");
+							}
+						}
+					}
+				}
+				// Foreach "down" legacy query, update its "up" counterpart
+				foreach ($aQueries[$sClass]['down'] as $sNeighbourId => $aNeighbourData)
+				{
+					if (!$aNeighbourData['_legacy_']) continue; // Skip modern definitions
+
+					$sLocalClass = $aNeighbourData['sFromClass'];
+					foreach (self::EnumChildClasses($aNeighbourData['sToClass'], ENUM_CHILD_CLASSES_ALL) as $sRemoteClass)
+					{
+						$aQueries[$sRemoteClass]['up'][$sLocalClass]['sQueryDown'] = $aNeighbourData['sQueryDown'];
+					}
+				}
 			}
 		}
+		return $aQueries;
+	}
 
-		// Merge legacy and new specs
-		$aLegacy = call_user_func_array(array($sClass, 'GetRelationQueries'), array($sRelCode));
-		foreach($aLegacy as $sId => $aLegacyEntry)
+	public static function EnumRelationQueries($sClass, $sRelCode, $bDown = true)
+	{
+		static $aQueries = array();
+		if (!isset($aQueries[$sRelCode]))
 		{
-			$aLegacyEntry['_legacy_'] = true;
-			$aNeighbours[] = array(
-				'_legacy_' => true,
-				'sQuery' => $aLegacyEntry['sQuery'],
-				'sNeighbour' => $sId
-			);
+			$aQueries[$sRelCode] = self::ComputeRelationQueries($sRelCode);
+		}
+		$sDirection = $bDown ? 'down' : 'up';
+		if (isset($aQueries[$sRelCode][$sClass][$sDirection]))
+		{
+			return $aQueries[$sRelCode][$sClass][$sDirection];
+		}
+		else
+		{
+			return array();
 		}
-		return $aNeighbours;
 	}
 
 	//

+ 11 - 0
datamodels/2.x/itop-bridge-virtualization-storage/datamodel.itop-bridge-virtualization-storage.xml

@@ -90,5 +90,16 @@
         </list>
       </presentation>
     </class>
+    <class id="LogicalVolume">
+      <relations>
+        <relation id="impacts">
+          <neighbours>
+            <neighbour id="VirtualDevice" _delta="define">
+              <attribute>virtualdevices_list</attribute>
+            </neighbour>
+          </neighbours>
+        </relation>
+      </relations>
+    </class>
   </classes>
 </itop_design>

+ 2 - 0
datamodels/2.x/itop-bridge-virtualization-storage/module.itop-bridge-virtualization-storage.php

@@ -13,6 +13,8 @@ SetupWebPage::AddModule(
 		// Setup
 		//
 		'dependencies' => array(
+			'itop-storage-mgmt/2.1.0',
+			'itop-virtualization-mgmt/2.1.0',
 		),
 		'mandatory' => false,
 		'visible' => true, // To prevent auto-install but shall not be listed in the install wizard

+ 4 - 4
datamodels/2.x/itop-config-mgmt/da.dict.itop-config-mgmt.php

@@ -597,11 +597,11 @@ Dict::Add('DA DA', 'Danish', 'Dansk', array(
 	'Class:LogicalInterface/Attribute:virtualmachine_id' => 'Virtuel maskine',
 	'Class:LogicalInterface/Attribute:virtualmachine_id+' => '',
 	'Relation:impacts/Description' => 'Elementer berørt af ...',
-	'Relation:impacts/VerbUp' => 'Påvrikning ...',
-	'Relation:impacts/VerbDown' => 'Elementer berørt af ...',
+	'Relation:impacts/DownStream' => 'Påvrikning ...',
+	'Relation:impacts/UpStream' => 'Elementer berørt af ...',
 	'Relation:depends on/Description' => 'Elementer, som afhænger af dette element',
-	'Relation:depends on/VerbUp' => 'Afhænger af ...',
-	'Relation:depends on/VerbDown' => 'Påvirker ...',
+	'Relation:depends on/DownStream' => 'Afhænger af ...',
+	'Relation:depends on/UpStream' => 'Påvirker ...',
 	'Class:Organization/Attribute:parent_name' => 'Parent name',
 	'Class:Organization/Attribute:parent_name+' => 'Parent name',
 	'Class:Organization/Attribute:deliverymodel_name' => 'Leveringsmodel navn',

+ 168 - 62
datamodels/2.x/itop-config-mgmt/datamodel.itop-config-mgmt.xml

@@ -1452,6 +1452,18 @@
           </items>
         </list>
       </presentation>
+      <methods>
+        <method id="GetRelationQueries">
+          <comment>/**
+	 * Placeholder for backward compatibility (iTop &lt;= 2.1.0)
+	 * in case an extension attempts to redefine this function...	 
+	 */</comment>
+          <static>true</static>
+          <access>public</access>
+          <type>Overload-DBObject</type>
+          <code><![CDATA[	public static function GetRelationQueries($sRelCode){return parent::GetRelationQueries($sRelCode);} ]]></code>
+        </method>
+      </methods>
       <relations>
         <relation id="impacts">
           <neighbours>
@@ -1854,15 +1866,18 @@
           </items>
         </list>
       </presentation>
-      <relations>
-        <relation id="depends on">
-          <neighbours>
-            <neighbour id="networkdevice">
-              <query>SELECT NetworkDevice AS nw JOIN lnkConnectableCIToNetworkDevice AS l1 ON l1.networkdevice_id = nw.id WHERE l1.connectableci_id = :this-&gt;id AND l1.connection_type='downlink'</query>
-            </neighbour>
-          </neighbours>
-        </relation>
-      </relations>
+      <methods>
+        <method id="GetRelationQueries">
+          <comment>/**
+	 * Placeholder for backward compatibility (iTop &lt;= 2.1.0)
+	 * in case an extension attempts to redefine this function...	 
+	 */</comment>
+          <static>true</static>
+          <access>public</access>
+          <type>Overload-DBObject</type>
+          <code><![CDATA[	public static function GetRelationQueries($sRelCode){return parent::GetRelationQueries($sRelCode);} ]]></code>
+        </method>
+      </methods>
     </class>
     <class id="DatacenterDevice" _delta="define">
       <parent>ConnectableCI</parent>
@@ -2383,11 +2398,24 @@
           </items>
         </list>
       </presentation>
+      <methods>
+        <method id="GetRelationQueries">
+          <comment>/**
+	 * Placeholder for backward compatibility (iTop &lt;= 2.1.0)
+	 * in case an extension attempts to redefine this function...	 
+	 */</comment>
+          <static>true</static>
+          <access>public</access>
+          <type>Overload-DBObject</type>
+          <code><![CDATA[	public static function GetRelationQueries($sRelCode){return parent::GetRelationQueries($sRelCode);} ]]></code>
+        </method>
+      </methods>
       <relations>
         <relation id="impacts">
           <neighbours>
             <neighbour id="connectableci">
-              <query>SELECT ConnectableCI AS d JOIN lnkConnectableCIToNetworkDevice AS l1 ON l1.connectableci_id = d.id WHERE l1.networkdevice_id = :this-&gt;id AND l1.connection_type='downlink'</query>
+              <query_down>SELECT ConnectableCI AS d JOIN lnkConnectableCIToNetworkDevice AS l1 ON l1.connectableci_id = d.id WHERE l1.networkdevice_id = :this-&gt;id AND l1.connection_type='downlink'</query_down>
+              <query_up>SELECT NetworkDevice AS nw JOIN lnkConnectableCIToNetworkDevice AS l1 ON l1.networkdevice_id = nw.id WHERE l1.connectableci_id = :this-&gt;id AND l1.connection_type='downlink'</query_up>
             </neighbour>
           </neighbours>
         </relation>
@@ -2694,6 +2722,28 @@
           </items>
         </list>
       </presentation>
+      <methods>
+        <method id="GetRelationQueries">
+          <comment>/**
+	 * Placeholder for backward compatibility (iTop &lt;= 2.1.0)
+	 * in case an extension attempts to redefine this function...	 
+	 */</comment>
+          <static>true</static>
+          <access>public</access>
+          <type>Overload-DBObject</type>
+          <code><![CDATA[	public static function GetRelationQueries($sRelCode){return parent::GetRelationQueries($sRelCode);} ]]></code>
+        </method>
+      </methods>
+      <relations>
+        <relation id="impacts">
+          <neighbours>
+            <neighbour id="hypervisor">
+              <query_down>SELECT Hypervisor AS o WHERE o.server_id = :this-&gt;id</query_down>
+              <query_up>SELECT Server AS o WHERE o.id = :this-&gt;server_id</query_up>
+            </neighbour>
+          </neighbours>
+        </relation>
+      </relations>
     </class>
     <class id="ApplicationSolution" _delta="define">
       <parent>FunctionalCI</parent>
@@ -2822,6 +2872,18 @@
           </items>
         </list>
       </presentation>
+      <methods>
+        <method id="GetRelationQueries">
+          <comment>/**
+	 * Placeholder for backward compatibility (iTop &lt;= 2.1.0)
+	 * in case an extension attempts to redefine this function...	 
+	 */</comment>
+          <static>true</static>
+          <access>public</access>
+          <type>Overload-DBObject</type>
+          <code><![CDATA[	public static function GetRelationQueries($sRelCode){return parent::GetRelationQueries($sRelCode);} ]]></code>
+        </method>
+      </methods>
       <relations>
         <relation id="impacts">
           <neighbours>
@@ -2830,13 +2892,6 @@
             </neighbour>
           </neighbours>
         </relation>
-        <relation id="depends on">
-          <neighbours>
-            <neighbour id="functionalci">
-              <attribute>functionalcis_list</attribute>
-            </neighbour>
-          </neighbours>
-        </relation>
       </relations>
     </class>
     <class id="BusinessProcess" _delta="define">
@@ -2949,15 +3004,18 @@
           </items>
         </list>
       </presentation>
-      <relations>
-        <relation id="depends on">
-          <neighbours>
-            <neighbour id="applicationsolution">
-              <attribute>applicationsolutions_list</attribute>
-            </neighbour>
-          </neighbours>
-        </relation>
-      </relations>
+      <methods>
+        <method id="GetRelationQueries">
+          <comment>/**
+	 * Placeholder for backward compatibility (iTop &lt;= 2.1.0)
+	 * in case an extension attempts to redefine this function...	 
+	 */</comment>
+          <static>true</static>
+          <access>public</access>
+          <type>Overload-DBObject</type>
+          <code><![CDATA[	public static function GetRelationQueries($sRelCode){return parent::GetRelationQueries($sRelCode);} ]]></code>
+        </method>
+      </methods>
     </class>
     <class id="SoftwareInstance" _delta="define">
       <parent>FunctionalCI</parent>
@@ -3123,15 +3181,18 @@
           </items>
         </list>
       </presentation>
-      <relations>
-        <relation id="depends on">
-          <neighbours>
-            <neighbour id="functionalci">
-              <query>SELECT FunctionalCI AS s JOIN SoftwareInstance AS app ON app.system_id = s.id WHERE app.id = :this-&gt;id</query>
-            </neighbour>
-          </neighbours>
-        </relation>
-      </relations>
+      <methods>
+        <method id="GetRelationQueries">
+          <comment>/**
+	 * Placeholder for backward compatibility (iTop &lt;= 2.1.0)
+	 * in case an extension attempts to redefine this function...	 
+	 */</comment>
+          <static>true</static>
+          <access>public</access>
+          <type>Overload-DBObject</type>
+          <code><![CDATA[	public static function GetRelationQueries($sRelCode){return parent::GetRelationQueries($sRelCode);} ]]></code>
+        </method>
+      </methods>
     </class>
     <class id="Middleware" _delta="define">
       <parent>SoftwareInstance</parent>
@@ -3259,6 +3320,18 @@
           </items>
         </list>
       </presentation>
+      <methods>
+        <method id="GetRelationQueries">
+          <comment>/**
+	 * Placeholder for backward compatibility (iTop &lt;= 2.1.0)
+	 * in case an extension attempts to redefine this function...	 
+	 */</comment>
+          <static>true</static>
+          <access>public</access>
+          <type>Overload-DBObject</type>
+          <code><![CDATA[	public static function GetRelationQueries($sRelCode){return parent::GetRelationQueries($sRelCode);} ]]></code>
+        </method>
+      </methods>
       <relations>
         <relation id="impacts">
           <neighbours>
@@ -3395,6 +3468,18 @@
           </items>
         </list>
       </presentation>
+      <methods>
+        <method id="GetRelationQueries">
+          <comment>/**
+	 * Placeholder for backward compatibility (iTop &lt;= 2.1.0)
+	 * in case an extension attempts to redefine this function...	 
+	 */</comment>
+          <static>true</static>
+          <access>public</access>
+          <type>Overload-DBObject</type>
+          <code><![CDATA[	public static function GetRelationQueries($sRelCode){return parent::GetRelationQueries($sRelCode);} ]]></code>
+        </method>
+      </methods>
       <relations>
         <relation id="impacts">
           <neighbours>
@@ -3531,6 +3616,18 @@
           </items>
         </list>
       </presentation>
+      <methods>
+        <method id="GetRelationQueries">
+          <comment>/**
+	 * Placeholder for backward compatibility (iTop &lt;= 2.1.0)
+	 * in case an extension attempts to redefine this function...	 
+	 */</comment>
+          <static>true</static>
+          <access>public</access>
+          <type>Overload-DBObject</type>
+          <code><![CDATA[	public static function GetRelationQueries($sRelCode){return parent::GetRelationQueries($sRelCode);} ]]></code>
+        </method>
+      </methods>
       <relations>
         <relation id="impacts">
           <neighbours>
@@ -3883,15 +3980,18 @@
           </items>
         </list>
       </presentation>
-      <relations>
-        <relation id="depends on">
-          <neighbours>
-            <neighbour id="middleware">
-              <attribute>middleware_id</attribute>
-            </neighbour>
-          </neighbours>
-        </relation>
-      </relations>
+      <methods>
+        <method id="GetRelationQueries">
+          <comment>/**
+	 * Placeholder for backward compatibility (iTop &lt;= 2.1.0)
+	 * in case an extension attempts to redefine this function...	 
+	 */</comment>
+          <static>true</static>
+          <access>public</access>
+          <type>Overload-DBObject</type>
+          <code><![CDATA[	public static function GetRelationQueries($sRelCode){return parent::GetRelationQueries($sRelCode);} ]]></code>
+        </method>
+      </methods>
     </class>
     <class id="DatabaseSchema" _delta="define">
       <parent>FunctionalCI</parent>
@@ -4001,15 +4101,18 @@
           </items>
         </list>
       </presentation>
-      <relations>
-        <relation id="depends on">
-          <neighbours>
-            <neighbour id="dbserver">
-              <attribute>dbserver_id</attribute>
-            </neighbour>
-          </neighbours>
-        </relation>
-      </relations>
+      <methods>
+        <method id="GetRelationQueries">
+          <comment>/**
+	 * Placeholder for backward compatibility (iTop &lt;= 2.1.0)
+	 * in case an extension attempts to redefine this function...	 
+	 */</comment>
+          <static>true</static>
+          <access>public</access>
+          <type>Overload-DBObject</type>
+          <code><![CDATA[	public static function GetRelationQueries($sRelCode){return parent::GetRelationQueries($sRelCode);} ]]></code>
+        </method>
+      </methods>
     </class>
     <class id="WebApplication" _delta="define">
       <parent>FunctionalCI</parent>
@@ -4128,15 +4231,18 @@
           </items>
         </list>
       </presentation>
-      <relations>
-        <relation id="depends on">
-          <neighbours>
-            <neighbour id="webserver">
-              <attribute>webserver_id</attribute>
-            </neighbour>
-          </neighbours>
-        </relation>
-      </relations>
+      <methods>
+        <method id="GetRelationQueries">
+          <comment>/**
+	 * Placeholder for backward compatibility (iTop &lt;= 2.1.0)
+	 * in case an extension attempts to redefine this function...	 
+	 */</comment>
+          <static>true</static>
+          <access>public</access>
+          <type>Overload-DBObject</type>
+          <code><![CDATA[	public static function GetRelationQueries($sRelCode){return parent::GetRelationQueries($sRelCode);} ]]></code>
+        </method>
+      </methods>
     </class>
     <class id="Software" _delta="define">
       <parent>cmdbAbstractObject</parent>

+ 4 - 4
datamodels/2.x/itop-config-mgmt/de.dict.itop-config-mgmt.php

@@ -424,11 +424,11 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
 	'Person:info' => 'Allgemeine Informationen',
 	'Person:notifiy' => 'Benachrichtigungen',
 	'Relation:impacts/Description' => 'Elemente betroffen von ...',
-	'Relation:impacts/VerbUp' => 'Auswirkung ...',
-	'Relation:impacts/VerbDown' => 'Elemente betroffen von ...',
+	'Relation:impacts/DownStream' => 'Auswirkung ...',
+	'Relation:impacts/UpStream' => 'Elemente betroffen von ...',
 	'Relation:depends on/Description' => 'Elemente, von denen dieses Element abhängt.',
-	'Relation:depends on/VerbUp' => 'Hängt ab von ...',
-	'Relation:depends on/VerbDown' => 'Wirkt auf ...',
+	'Relation:depends on/DownStream' => 'Hängt ab von ...',
+	'Relation:depends on/UpStream' => 'Wirkt auf ...',
 	'Class:Organization/Attribute:parent_name' => 'Name der Mutterfirma',
 	'Class:Organization/Attribute:parent_name+' => 'Name der Mutterfirma',
 	'Class:Organization/Attribute:parent_id_friendlyname' => 'Parent',

+ 4 - 4
datamodels/2.x/itop-config-mgmt/en.dict.itop-config-mgmt.php

@@ -31,11 +31,11 @@
 
 Dict::Add('EN US', 'English', 'English', array(
 	'Relation:impacts/Description' => 'Elements impacted by',
-	'Relation:impacts/VerbUp' => 'Impact...',
-	'Relation:impacts/VerbDown' => 'Elements impacted by...',
+	'Relation:impacts/DownStream' => 'Impact...',
+	'Relation:impacts/UpStream' => 'Elements impacted by...',
 	'Relation:depends on/Description' => 'Elements impacting',
-	'Relation:depends on/VerbUp' => 'Depends on...',
-	'Relation:depends on/VerbDown' => 'Impacts...',
+	'Relation:depends on/DownStream' => 'Depends on...',
+	'Relation:depends on/UpStream' => 'Impacts...',
 ));
 
 

+ 4 - 4
datamodels/2.x/itop-config-mgmt/es_cr.dict.itop-config-mgmt.php

@@ -32,11 +32,11 @@
 
 Dict::Add('ES CR', 'Spanish', 'Español, Castellano', array(
 	'Relation:impacts/Description' => 'Elementos Impactados por',
-	'Relation:impacts/VerbUp' => 'Impacto...',
-	'Relation:impacts/VerbDown' => 'Elementos Impactados por...',
+	'Relation:impacts/DownStream' => 'Impacto...',
+	'Relation:impacts/UpStream' => 'Elementos Impactados por...',
 	'Relation:depends on/Description' => 'Elementos de los cuales depende',
-	'Relation:depends on/VerbUp' => 'Depende de...',
-	'Relation:depends on/VerbDown' => 'Impactos...',
+	'Relation:depends on/DownStream' => 'Depende de...',
+	'Relation:depends on/UpStream' => 'Impactos...',
 ));
 
 

+ 4 - 4
datamodels/2.x/itop-config-mgmt/fr.dict.itop-config-mgmt.php

@@ -1819,11 +1819,11 @@ Dict::Add('FR FR', 'French', 'Français', array(
 	'UI-ConfigMgmtMenuOverview-DeviceToRenew' => 'Equipements à remplacer dans 6 mois',
 	'Menu:UI_WelcomeMenu_AllConfigItems' => 'Résumé',
 	'Relation:impacts/Description' => 'Eléments impactés par',
-	'Relation:impacts/VerbUp' => 'Impacte...',
-	'Relation:impacts/VerbDown' => 'Dépend de...',
+	'Relation:impacts/DownStream' => 'Impacte...',
+	'Relation:impacts/UpStream' => 'Dépend de...',
 	'Relation:depends on/Description' => 'Eléments dont dépend',
-	'Relation:depends on/VerbUp' => 'Dépend de...',
-	'Relation:depends on/VerbDown' => 'Impacte...',
+	'Relation:depends on/DownStream' => 'Dépend de...',
+	'Relation:depends on/UpStream' => 'Impacte...',
 	'Menu:ConfigManagement:Typology' => 'Configuration des typologies',
 ));
 

+ 4 - 4
datamodels/2.x/itop-config-mgmt/hu.dict.itop-config-mgmt.php

@@ -383,11 +383,11 @@ Dict::Add('HU HU', 'Hungarian', 'Magyar', array(
 	'Class:lnkProcessToSolution/Attribute:reason' => 'Ok',
 	'Class:lnkProcessToSolution/Attribute:reason+' => '',
 	'Relation:impacts/Description' => 'Konfigurációs elem működését befolyásolják',
-	'Relation:impacts/VerbUp' => 'Hatás',
-	'Relation:impacts/VerbDown' => 'Konfigurációs elem működését befolyásolják',
+	'Relation:impacts/DownStream' => 'Hatás',
+	'Relation:impacts/UpStream' => 'Konfigurációs elem működését befolyásolják',
 	'Relation:depends on/Description' => 'Konfigurációs elemtől függnek',
-	'Relation:depends on/VerbUp' => 'Függőségek',
-	'Relation:depends on/VerbDown' => 'Hatások',
+	'Relation:depends on/DownStream' => 'Függőségek',
+	'Relation:depends on/UpStream' => 'Hatások',
 	'Class:Organization/Attribute:parent_name' => 'Felérendelt szervezeti egység neve',
 	'Class:Organization/Attribute:parent_name+' => '',
 	'Class:Location/Attribute:org_name' => 'Tulejdonos szevezeti egység neve',

+ 4 - 4
datamodels/2.x/itop-config-mgmt/it.dict.itop-config-mgmt.php

@@ -383,11 +383,11 @@ Dict::Add('IT IT', 'Italian', 'Italiano', array(
 	'Class:lnkProcessToSolution/Attribute:reason' => 'Motivo',
 	'Class:lnkProcessToSolution/Attribute:reason+' => 'Più informazioni tra il processo di business e la soluzione applicativa',
 	'Relation:impacts/Description' => 'Elementi impattati da...',
-	'Relation:impacts/VerbUp' => 'Impatto...',
-	'Relation:impacts/VerbDown' => 'Elementi impattati da...',
+	'Relation:impacts/DownStream' => 'Impatto...',
+	'Relation:impacts/UpStream' => 'Elementi impattati da...',
 	'Relation:depends on/Description' => 'Elementi di questo elemento dipende da',
-	'Relation:depends on/VerbUp' => 'Dipende da...',
-	'Relation:depends on/VerbDown' => 'Impatto...',
+	'Relation:depends on/DownStream' => 'Dipende da...',
+	'Relation:depends on/UpStream' => 'Impatto...',
 	'Class:Organization/Attribute:parent_name' => 'Parent name',
 	'Class:Organization/Attribute:parent_name+' => 'Name of the parent organization',
 	'Class:Location/Attribute:org_name' => 'Nome dell\'organizzazione',

+ 4 - 4
datamodels/2.x/itop-config-mgmt/ja.dict.itop-config-mgmt.php

@@ -595,11 +595,11 @@ Dict::Add('JA JP', 'Japanese', '日本語', array(
 	'Class:LogicalInterface/Attribute:virtualmachine_id' => '仮想マシン',
 	'Class:LogicalInterface/Attribute:virtualmachine_id+' => '',
 	'Relation:impacts/Description' => 'インパクトを受ける要素',
-	'Relation:impacts/VerbUp' => 'インパクト...',
-	'Relation:impacts/VerbDown' => 'インパクトを受ける要素',
+	'Relation:impacts/DownStream' => 'インパクト...',
+	'Relation:impacts/UpStream' => 'インパクトを受ける要素',
 	'Relation:depends on/Description' => 'この要素が依存している要素',
-	'Relation:depends on/VerbUp' => '依存...',
-	'Relation:depends on/VerbDown' => 'インパクト...',
+	'Relation:depends on/DownStream' => '依存...',
+	'Relation:depends on/UpStream' => 'インパクト...',
 	'Class:Organization/Attribute:parent_name' => '親名前',
 	'Class:Organization/Attribute:parent_name+' => '親組織の名前',
 	'Class:Organization/Attribute:deliverymodel_name' => '提供モデル名',

+ 4 - 4
datamodels/2.x/itop-config-mgmt/nl.dict.itop-config-mgmt.php

@@ -34,11 +34,11 @@
 
 Dict::Add('NL NL', 'Dutch', 'Nederlands', array(
 	'Relation:impacts/Description' => 'Elementen hebben impact op',
-	'Relation:impacts/VerbUp' => 'Impact...',
-	'Relation:impacts/VerbDown' => 'Elementen...',
+	'Relation:impacts/DownStream' => 'Impact...',
+	'Relation:impacts/UpStream' => 'Elementen...',
 	'Relation:depends on/Description' => 'Elementen waarvan dit element afhankelijk van is',
-	'Relation:depends on/VerbUp' => 'Is afhankelijk van...',
-	'Relation:depends on/VerbDown' => 'Impacts...',
+	'Relation:depends on/DownStream' => 'Is afhankelijk van...',
+	'Relation:depends on/UpStream' => 'Impacts...',
 ));
 
 

+ 4 - 4
datamodels/2.x/itop-config-mgmt/pt_br.dict.itop-config-mgmt.php

@@ -31,11 +31,11 @@
 
 Dict::Add('PT BR', 'Brazilian', 'Brazilian', array(
 	'Relation:impacts/Description' => 'Elementos impactados por',
-	'Relation:impacts/VerbUp' => 'Impacto...',
-	'Relation:impacts/VerbDown' => 'Elementos impactados por...',
+	'Relation:impacts/DownStream' => 'Impacto...',
+	'Relation:impacts/UpStream' => 'Elementos impactados por...',
 	'Relation:depends on/Description' => 'Elementos estes, que dependem deste elemento',
-	'Relation:depends on/VerbUp' => 'Depende de...',
-	'Relation:depends on/VerbDown' => 'Impactos...',
+	'Relation:depends on/DownStream' => 'Depende de...',
+	'Relation:depends on/UpStream' => 'Impactos...',
 ));
 
 

+ 4 - 4
datamodels/2.x/itop-config-mgmt/ru.dict.itop-config-mgmt.php

@@ -26,11 +26,11 @@
 
 Dict::Add('RU RU', 'Russian', 'Русский', array(
 	'Relation:impacts/Description' => 'Элементы, на которые влияет',
-	'Relation:impacts/VerbUp' => 'Влияние...',
-	'Relation:impacts/VerbDown' => 'Элементы, на которые влияет...',
+	'Relation:impacts/DownStream' => 'Влияние...',
+	'Relation:impacts/UpStream' => 'Элементы, на которые влияет...',
 	'Relation:depends on/Description' => 'Элементы, от которых зависит',
-	'Relation:depends on/VerbUp' => 'Зависимость...',
-	'Relation:depends on/VerbDown' => 'Влияние...',
+	'Relation:depends on/DownStream' => 'Зависимость...',
+	'Relation:depends on/UpStream' => 'Влияние...',
 ));
 
 

+ 4 - 4
datamodels/2.x/itop-config-mgmt/tr.dict.itop-config-mgmt.php

@@ -32,11 +32,11 @@
 
 Dict::Add('TR TR', 'Turkish', 'Türkçe', array(
 	'Relation:impacts/Description' => 'Etkilenen kalemler',
-	'Relation:impacts/VerbUp' => 'Etkiler...',
-	'Relation:impacts/VerbDown' => 'Etkilenenler...',
+	'Relation:impacts/DownStream' => 'Etkiler...',
+	'Relation:impacts/UpStream' => 'Etkilenenler...',
 	'Relation:depends on/Description' => 'Bu kaleme bağımlı olan kalemler',
-	'Relation:depends on/VerbUp' => 'Bağımlı olanlar...',
-	'Relation:depends on/VerbDown' => 'Etkiledikleri...',
+	'Relation:depends on/DownStream' => 'Bağımlı olanlar...',
+	'Relation:depends on/UpStream' => 'Etkiledikleri...',
 ));
 
 

+ 4 - 4
datamodels/2.x/itop-config-mgmt/zh.dict.itop-config-mgmt.php

@@ -32,11 +32,11 @@
 
 Dict::Add('ZH CN', 'Chinese', '简体中文', array(
 	'Relation:impacts/Description' => '被影响的元素',
-	'Relation:impacts/VerbUp' => '影响...',
-	'Relation:impacts/VerbDown' => '被影响的元素...',
+	'Relation:impacts/DownStream' => '影响...',
+	'Relation:impacts/UpStream' => '被影响的元素...',
 	'Relation:depends on/Description' => '该元素依赖的元素...',
-	'Relation:depends on/VerbUp' => '依赖于...',
-	'Relation:depends on/VerbDown' => '影响...',
+	'Relation:depends on/DownStream' => '依赖于...',
+	'Relation:depends on/UpStream' => '影响...',
 ));
 
 

+ 16 - 11
datamodels/2.x/itop-datacenter-mgmt/datamodel.itop-datacenter-mgmt.xml

@@ -531,10 +531,12 @@
         <relation id="impacts">
           <neighbours>
             <neighbour id="datacenterdevice">
-              <query>SELECT DatacenterDevice WHERE powerA_id = :this-&gt;id OR powerB_id = :this-&gt;id</query>
+              <query_down>SELECT DatacenterDevice WHERE powerA_id = :this-&gt;id OR powerB_id = :this-&gt;id</query_down>
+              <query_up>SELECT PowerConnection WHERE id = :this-&gt;powerA_id OR id = :this-&gt;powerB_id</query_up>
             </neighbour>
             <neighbour id="pdu">
-              <query>SELECT PDU WHERE powerstart_id = :this-&gt;id</query>
+              <query_down>SELECT PDU WHERE powerstart_id = :this-&gt;id</query_down>
+              <query_up>SELECT PowerConnection WHERE id = :this-&gt;powerstart_id</query_up>
             </neighbour>
           </neighbours>
         </relation>
@@ -895,15 +897,18 @@
           </items>
         </list>
       </presentation>
-      <relations>
-        <relation id="depends on">
-          <neighbours>
-            <neighbour id="powerconnection">
-              <attribute>powerstart_id</attribute>
-            </neighbour>
-          </neighbours>
-        </relation>
-      </relations>
+      <methods>
+        <method id="GetRelationQueries">
+          <comment>/**
+	 * Placeholder for backward compatibility (iTop &lt;= 2.1.0)
+	 * in case an extension attempts to redefine this function...	 
+	 */</comment>
+          <static>true</static>
+          <access>public</access>
+          <type>Overload-DBObject</type>
+          <code><![CDATA[	public static function GetRelationQueries($sRelCode){return parent::GetRelationQueries($sRelCode);} ]]></code>
+        </method>
+      </methods>
     </class>
   </classes>
   <menus>

+ 84 - 25
datamodels/2.x/itop-storage-mgmt/datamodel.itop-storage-mgmt.xml

@@ -235,6 +235,18 @@
           </items>
         </list>
       </presentation>
+      <methods>
+        <method id="GetRelationQueries">
+          <comment>/**
+	 * Placeholder for backward compatibility (iTop &lt;= 2.1.0)
+	 * in case an extension attempts to redefine this function...	 
+	 */</comment>
+          <static>true</static>
+          <access>public</access>
+          <type>Overload-DBObject</type>
+          <code><![CDATA[	public static function GetRelationQueries($sRelCode){return parent::GetRelationQueries($sRelCode);} ]]></code>
+        </method>
+      </methods>
       <relations>
         <relation id="impacts">
           <neighbours>
@@ -477,6 +489,18 @@
           </items>
         </list>
       </presentation>
+      <methods>
+        <method id="GetRelationQueries">
+          <comment>/**
+	 * Placeholder for backward compatibility (iTop &lt;= 2.1.0)
+	 * in case an extension attempts to redefine this function...	 
+	 */</comment>
+          <static>true</static>
+          <access>public</access>
+          <type>Overload-DBObject</type>
+          <code><![CDATA[	public static function GetRelationQueries($sRelCode){return parent::GetRelationQueries($sRelCode);} ]]></code>
+        </method>
+      </methods>
       <relations>
         <relation id="impacts">
           <neighbours>
@@ -718,6 +742,18 @@
           </items>
         </list>
       </presentation>
+      <methods>
+        <method id="GetRelationQueries">
+          <comment>/**
+	 * Placeholder for backward compatibility (iTop &lt;= 2.1.0)
+	 * in case an extension attempts to redefine this function...	 
+	 */</comment>
+          <static>true</static>
+          <access>public</access>
+          <type>Overload-DBObject</type>
+          <code><![CDATA[	public static function GetRelationQueries($sRelCode){return parent::GetRelationQueries($sRelCode);} ]]></code>
+        </method>
+      </methods>
       <relations>
         <relation id="impacts">
           <neighbours>
@@ -959,6 +995,18 @@
           </items>
         </list>
       </presentation>
+      <methods>
+        <method id="GetRelationQueries">
+          <comment>/**
+	 * Placeholder for backward compatibility (iTop &lt;= 2.1.0)
+	 * in case an extension attempts to redefine this function...	 
+	 */</comment>
+          <static>true</static>
+          <access>public</access>
+          <type>Overload-DBObject</type>
+          <code><![CDATA[	public static function GetRelationQueries($sRelCode){return parent::GetRelationQueries($sRelCode);} ]]></code>
+        </method>
+      </methods>
       <relations>
         <relation id="impacts">
           <neighbours>
@@ -1058,15 +1106,18 @@
           </items>
         </list>
       </presentation>
-      <relations>
-        <relation id="depends on">
-          <neighbours>
-            <neighbour id="tapelibrary">
-              <attribute>tapelibrary_id</attribute>
-            </neighbour>
-          </neighbours>
-        </relation>
-      </relations>
+      <methods>
+        <method id="GetRelationQueries">
+          <comment>/**
+	 * Placeholder for backward compatibility (iTop &lt;= 2.1.0)
+	 * in case an extension attempts to redefine this function...	 
+	 */</comment>
+          <static>true</static>
+          <access>public</access>
+          <type>Overload-DBObject</type>
+          <code><![CDATA[	public static function GetRelationQueries($sRelCode){return parent::GetRelationQueries($sRelCode);} ]]></code>
+        </method>
+      </methods>
     </class>
     <class id="NASFileSystem" _delta="define">
       <parent>cmdbAbstractObject</parent>
@@ -1171,15 +1222,18 @@
           </items>
         </list>
       </presentation>
-      <relations>
-        <relation id="depends on">
-          <neighbours>
-            <neighbour id="nas">
-              <attribute>nas_id</attribute>
-            </neighbour>
-          </neighbours>
-        </relation>
-      </relations>
+      <methods>
+        <method id="GetRelationQueries">
+          <comment>/**
+	 * Placeholder for backward compatibility (iTop &lt;= 2.1.0)
+	 * in case an extension attempts to redefine this function...	 
+	 */</comment>
+          <static>true</static>
+          <access>public</access>
+          <type>Overload-DBObject</type>
+          <code><![CDATA[	public static function GetRelationQueries($sRelCode){return parent::GetRelationQueries($sRelCode);} ]]></code>
+        </method>
+      </methods>
     </class>
     <class id="FiberChannelInterface" _delta="define">
       <parent>NetworkInterface</parent>
@@ -1429,6 +1483,18 @@
           </items>
         </list>
       </presentation>
+      <methods>
+        <method id="GetRelationQueries">
+          <comment>/**
+	 * Placeholder for backward compatibility (iTop &lt;= 2.1.0)
+	 * in case an extension attempts to redefine this function...	 
+	 */</comment>
+          <static>true</static>
+          <access>public</access>
+          <type>Overload-DBObject</type>
+          <code><![CDATA[	public static function GetRelationQueries($sRelCode){return parent::GetRelationQueries($sRelCode);} ]]></code>
+        </method>
+      </methods>
       <relations>
         <relation id="impacts">
           <neighbours>
@@ -1437,13 +1503,6 @@
             </neighbour>
           </neighbours>
         </relation>
-        <relation id="depends on">
-          <neighbours>
-            <neighbour id="storagesystem">
-              <attribute>storagesystem_id</attribute>
-            </neighbour>
-          </neighbours>
-        </relation>
       </relations>
     </class>
     <class id="lnkServerToVolume" _delta="define">

+ 48 - 25
datamodels/2.x/itop-virtualization-mgmt/datamodel.itop-virtualization-mgmt.xml

@@ -232,6 +232,18 @@
           </items>
         </list>
       </presentation>
+      <methods>
+        <method id="GetRelationQueries">
+          <comment>/**
+	 * Placeholder for backward compatibility (iTop &lt;= 2.1.0)
+	 * in case an extension attempts to redefine this function...	 
+	 */</comment>
+          <static>true</static>
+          <access>public</access>
+          <type>Overload-DBObject</type>
+          <code><![CDATA[	public static function GetRelationQueries($sRelCode){return parent::GetRelationQueries($sRelCode);} ]]></code>
+        </method>
+      </methods>
       <relations>
         <relation id="impacts">
           <neighbours>
@@ -378,6 +390,18 @@
           </items>
         </list>
       </presentation>
+      <methods>
+        <method id="GetRelationQueries">
+          <comment>/**
+	 * Placeholder for backward compatibility (iTop &lt;= 2.1.0)
+	 * in case an extension attempts to redefine this function...	 
+	 */</comment>
+          <static>true</static>
+          <access>public</access>
+          <type>Overload-DBObject</type>
+          <code><![CDATA[	public static function GetRelationQueries($sRelCode){return parent::GetRelationQueries($sRelCode);} ]]></code>
+        </method>
+      </methods>
       <relations>
         <relation id="impacts">
           <neighbours>
@@ -386,13 +410,6 @@
             </neighbour>
           </neighbours>
         </relation>
-        <relation id="depends on">
-          <neighbours>
-            <neighbour id="server">
-              <attribute>server_id</attribute>
-            </neighbour>
-          </neighbours>
-        </relation>
       </relations>
     </class>
     <class id="Farm" _delta="define">
@@ -512,15 +529,18 @@
           </items>
         </list>
       </presentation>
-      <relations>
-        <relation id="depends on">
-          <neighbours>
-            <neighbour id="hypervisor">
-              <attribute>hypervisor_list</attribute>
-           </neighbour>
-          </neighbours>
-        </relation>
-      </relations>
+      <methods>
+        <method id="GetRelationQueries">
+          <comment>/**
+	 * Placeholder for backward compatibility (iTop &lt;= 2.1.0)
+	 * in case an extension attempts to redefine this function...	 
+	 */</comment>
+          <static>true</static>
+          <access>public</access>
+          <type>Overload-DBObject</type>
+          <code><![CDATA[	public static function GetRelationQueries($sRelCode){return parent::GetRelationQueries($sRelCode);} ]]></code>
+        </method>
+      </methods>
     </class>
     <class id="VirtualMachine" _delta="define">
       <parent>VirtualDevice</parent>
@@ -751,15 +771,18 @@
           </items>
         </list>
       </presentation>
-      <relations>
-        <relation id="depends on">
-          <neighbours>
-            <neighbour id="virtualhost">
-              <attribute>virtualhost_id</attribute>
-            </neighbour>
-          </neighbours>
-        </relation>
-      </relations>
+      <methods>
+        <method id="GetRelationQueries">
+          <comment>/**
+	 * Placeholder for backward compatibility (iTop &lt;= 2.1.0)
+	 * in case an extension attempts to redefine this function...	 
+	 */</comment>
+          <static>true</static>
+          <access>public</access>
+          <type>Overload-DBObject</type>
+          <code><![CDATA[	public static function GetRelationQueries($sRelCode){return parent::GetRelationQueries($sRelCode);} ]]></code>
+        </method>
+      </methods>
     </class>
     <class id="LogicalInterface" _delta="define">
       <parent>IPInterface</parent>

File diff suppressed because it is too large
+ 1417 - 1417
dictionaries/da.dictionary.itop.core.php


+ 3 - 2
pages/schema.php

@@ -530,7 +530,8 @@ function DisplayRelationDetails($oPage, $sRelCode, $sContext)
 			$oPage->add("<ul>\n");
 			foreach ($aRelQueries as $sRelKey => $aQuery)
 			{
-				$sQuery = isset($aQuery['sQuery']) ? $aQuery['sQuery'] : '';
+				$sQueryDown = isset($aQuery['sQueryDown']) ? $aQuery['sQueryDown'] : '';
+				$sQueryUp = isset($aQuery['sQueryUp']) ? $aQuery['sQueryUp'] : '';
 				$sAttribute = isset($aQuery['sAttribute']) ? $aQuery['sAttribute'] : '';
 				/*
 				if ($aQuery['bPropagate'])
@@ -542,7 +543,7 @@ function DisplayRelationDetails($oPage, $sRelCode, $sContext)
 					$oPage->add("<li>".Dict::Format('UI:Schema:RelationDoesNotPropagate', $sRelKey, $iDistance, $sQuery)."</li>\n");
 				}
 				*/
-				$sLabel = (strlen($sQuery) > 0) ? $sQuery : $sAttribute;
+				$sLabel = (strlen($sQueryDown) > 0) ? $sQueryDown : $sAttribute;
 				if ($aQuery['_legacy_'])
 				{
 					$sLabel .= ' (<b>Old style specification</b>: it is recommended to upgrade to XML)';

+ 14 - 13
setup/compiler.class.inc.php

@@ -1420,30 +1420,31 @@ EOF;
 					if ($oNeighbour->tagName != 'neighbour') continue;
 					$sNeighbourId = $oNeighbour->getAttribute('id');
 
-					if (($oNeighbour->GetChildText('query') == '') && ($oNeighbour->GetChildText('attribute') == ''))
+					if (($oNeighbour->GetChildText('query_down') != '') && ($oNeighbour->GetChildText('query_up') == ''))
 					{
-						throw new DOMFormatException("Relation '$sRelationId': either a query or an attribute must be specified");
+						throw new DOMFormatException("Relation '$sRelationId/$sNeighbourId': missing the query_up specification");
 					}
-					if (($oNeighbour->GetChildText('query') != '') && ($oNeighbour->GetChildText('attribute') != ''))
+					if (($oNeighbour->GetChildText('query_up') != '') && ($oNeighbour->GetChildText('query_down') == ''))
 					{
-						throw new DOMFormatException("Relation '$sRelationId': both a query and and attribute have been specified... which one should be used?");
+						throw new DOMFormatException("Relation '$sRelationId/$sNeighbourId': missing the query_down specification");
+					}
+					if (($oNeighbour->GetChildText('query_down') == '') && ($oNeighbour->GetChildText('attribute') == ''))
+					{
+						throw new DOMFormatException("Relation '$sRelationId/$sNeighbourId': either a query or an attribute must be specified");
+					}
+					if (($oNeighbour->GetChildText('query_down') != '') && ($oNeighbour->GetChildText('attribute') != ''))
+					{
+						throw new DOMFormatException("Relation '$sRelationId/$sNeighbourId': both a query and and attribute have been specified... which one should be used?");
 					}
 					$aData = array(
 						'_legacy_' => false,
 						'sDefinedInClass' => $sClass,
 						'sNeighbour' => $sNeighbourId,
-						'sQuery' => $oNeighbour->GetChildText('query'),
+						'sQueryDown' => $oNeighbour->GetChildText('query_down'),
+						'sQueryUp' => $oNeighbour->GetChildText('query_up'),
 						'sAttribute' => $oNeighbour->GetChildText('attribute'),
 					);
 
-					$oReverse = $oNeighbour->GetOptionalElement('reverse');
-					if ($oReverse)
-					{
-						$aData['sReverseClass'] = $oReverse->GetChildText('source_class');
-						$aData['sReverseRelation'] = $oReverse->GetChildText('relation');
-						$aData['sReverseNeighbour'] = $oReverse->GetChildText('neighbour');
-					}
-
 					$oRedundancy = $oNeighbour->GetOptionalElement('redundancy');
 					if ($oRedundancy)
 					{

Some files were not shown because too many files changed in this diff