sbsv2/raptor/python/raptor_xml.py
changeset 674 37ee82a83d43
parent 625 a1925fb7753a
--- a/sbsv2/raptor/python/raptor_xml.py	Tue Nov 02 16:54:53 2010 +0800
+++ b/sbsv2/raptor/python/raptor_xml.py	Fri Nov 12 14:49:36 2010 +0000
@@ -173,10 +173,19 @@
 class SystemModel(object):
 	"""A representation of the SystemModel section of a Symbian system_definition.xml file."""
 
-	def __init__(self, aLogger, aSystemDefinitionFile, aSystemDefinitionBase):
+	def __init__(self, aLogger, aSystemDefinitionFile = None, aSystemDefinitionBase = None, aDoRead = True):
 		self.__Logger = aLogger
-		self.__SystemDefinitionFile = aSystemDefinitionFile.GetLocalString()
-		self.__SystemDefinitionBase = aSystemDefinitionBase.GetLocalString()
+
+		if aSystemDefinitionFile:
+			self.__SystemDefinitionFile = aSystemDefinitionFile.GetLocalString()
+		else:
+			self.__SystemDefinitionFile = generic_path.Path('undefined').GetLocalString()
+
+		if aSystemDefinitionBase:
+			self.__SystemDefinitionBase = aSystemDefinitionBase.GetLocalString()
+		else:
+			self.__SystemDefinitionBase = generic_path.Path('undefined').GetLocalString()
+
 		self.__Version = {'MAJOR':0,'MID':0,'MINOR':0}
 		self.__IdAttribute = "name"
 		self.__ComponentRoot = ""
@@ -188,12 +197,13 @@
 		self.__DOM = None
 		self.__SystemDefinitionElement = None
 
-		if self.__Read():
-			if self.__Validate():
-				self.__Parse()
+		if aDoRead:
+			if self.__Read():
+				if self.__Validate():
+					self.__Parse()
 
-		if self.__DOM:
-			self.__DOM.unlink()
+			if self.__DOM:
+				self.__DOM.unlink()
 
 	def HasLayer(self, aLayer):
 		return aLayer in self.__LayerList
@@ -201,6 +211,24 @@
 	def GetLayerNames(self):
 		return self.__LayerList
 
+	def AddComponent(self, aComponent):
+		'''Add a dummy component, sufficient for the purposes of
+		writing a new system definition file. Argument is a Raptor
+		Component object.
+		'''
+		layername = aComponent.layername
+		if layername == '':
+			raise Exception("Can't add a component ("+str(aComponent.bldinf_filename)+") without a layer name to a system defintion file")
+		containers = {'layer':layername,'component':aComponent.componentname}
+		component = SystemModelComponent(aComponent.bldinf_filename, layername, containers, self.__SystemDefinitionFile, self.__SystemDefinitionBase, self.__Version)
+
+		if not layername in self.__LayerList:
+			self.__LayerList.append(layername)
+
+		if not self.__LayerDetails.has_key(layername):
+			self.__LayerDetails[layername] = []
+		self.__LayerDetails[layername].append(component)
+
 	def GetLayerComponents(self, aLayer):
 		if not self.HasLayer(aLayer):
 			self.__Logger.Error("System Definition layer \"%s\" does not exist in %s", aLayer, self.__SystemDefinitionFile)
@@ -226,7 +254,6 @@
 			components.extend(self.GetLayerComponents(layer))
 
 		return components
-
 	def DumpLayerInfo(self, aLayer):
 		if self.HasLayer(aLayer):
 			self.__Logger.Info("Found %d bld.inf references in layer \"%s\"", len(self.GetLayerComponents(aLayer)), aLayer)
@@ -238,6 +265,45 @@
 				count = len(self.GetLayerNames()))
 		self.__Logger.InfoDiscovery(object_type = "bld.inf references",
 				count = len(self.GetAllComponents()))
+		
+	def Write(self, aFilename):
+		"""Write out a system definition that can be used to create an
+		identical SystemModel object.
+		Note it isn't guaranteed to be a valid system definition - just one
+		that will unserialise to an object identical to this one
+		"""
+		impl = xml.dom.minidom.getDOMImplementation()
+		self.__DOM = impl.createDocument(None, "SystemDefinition", None)
+		self.__SystemDefinitionElement = self.__DOM.documentElement
+		self.__DOM.insertBefore(self.__DOM.createComment('This document is generated by Raptor.  Please do not edit.'),self.__SystemDefinitionElement)
+		self.__SystemDefinitionElement.setAttribute('name','MCL')
+		self.__SystemDefinitionElement.setAttribute('schema','2.0.0')
+		systemModelNode = self.__DOM.createElement('systemModel')
+		self.__SystemDefinitionElement.appendChild(systemModelNode)
+		for layer in self.__LayerList:
+			if len(self.__LayerDetails[layer]) == 0:
+				continue
+			if layer == '':
+				self.__Logger.Error("Can't write out layer with no name to "+aFilename)
+			else:
+				layerNode = self.__DOM.createElement('layer')
+				layerNode.setAttribute('name',layer)
+				systemModelNode.appendChild(layerNode)
+				for component in self.__LayerDetails[layer]:
+					componentNode = self.__DOM.createElement('component')
+					componentNode.setAttribute('name',component.GetContainerName('component'))
+					layerNode.appendChild(componentNode)
+					path = str(component)
+					unitNode = self.__DOM.createElement('unit')
+					unitNode.setAttribute('bldFile',path)
+					componentNode.appendChild(unitNode)
+		
+		# Record that we haven't stripped the file names off our bld.infs
+		self.__SystemDefinitionElement.setAttribute('fullbldinfs','True')
+
+		self.__DOM.writexml(open(aFilename,"w"),newl="\n",indent="",addindent="\t")
+
+		self.__DOM.unlink()		
 
 	def __Read(self):
 		if not os.path.exists(self.__SystemDefinitionFile):
@@ -273,6 +339,12 @@
 		self.__Version['MID'] = int(version.group('MID'))
 		self.__Version['MINOR'] = int(version.group('MINOR'))
 
+		self.__fullbldinfs = None
+		if self.__SystemDefinitionElement.hasAttribute('fullbldinfs'):
+			# Lower case it since we're not evil
+			if self.__SystemDefinitionElement.getAttribute('fullbldinfs').lower() == 'true':
+				self.__fullbldinfs = 1
+
 		if self.__Version['MAJOR'] == 1 and self.__Version['MID'] > 2:
 			self.__ComponentRoot = self.__SystemDefinitionBase
 		elif self.__Version['MAJOR'] == 2 or self.__Version['MAJOR'] == 3:
@@ -382,27 +454,31 @@
 							self.__Logger.Error("Cannot resolve \'root\' attribute value \"%s\" in %s", rootValue, self.__SystemDefinitionFile)
 							return
 
-				group = generic_path.Path(bldFileValue)
+				bldinfval = generic_path.Path(bldFileValue)
 
 				if self.__Version['MAJOR'] < 3:
 					# absolute paths are not changed by root var in 1.x and 2.x
-					if not group.isAbsolute() and bldInfRoot:
-						group = generic_path.Join(bldInfRoot, group)
+					if not bldinfval.isAbsolute() and bldInfRoot:
+						bldinfval = generic_path.Join(bldInfRoot, bldinfval)
 				else:
 					# relative paths for v3
-					if not group.isAbsolute():
-						group = generic_path.Join(generic_path.Join(self.__SystemDefinitionFile).Dir(),group)
+					if not bldinfval.isAbsolute():
+						bldinfval = generic_path.Join(generic_path.Join(self.__SystemDefinitionFile).Dir(),bldinfval)
 					# absolute paths for v3
 					# are relative to bldInfRoot if set, or relative to the drive root otherwise
 					elif bldInfRoot:
-						group = generic_path.Join(bldInfRoot, group)
-
-				bldinf = generic_path.Join(group, "bld.inf").FindCaseless()
+						bldinfval = generic_path.Join(bldInfRoot, bldinfval)
+				
+				if self.__fullbldinfs:
+					bldinf = bldinfval.FindCaseless()
+				else:
+					bldinf = generic_path.Join(bldinfval, "bld.inf").FindCaseless()
 
 				if bldinf == None:
 					# recording layers containing non existent bld.infs
-					bldinfname = group.GetLocalString()
-					bldinfname = bldinfname+'/'+'bld.inf'
+					bldinfname = bldinfval.GetLocalString()
+					if not self.__fullbldinfs:
+						bldinfname = bldinfname+'/'+'bld.inf'
 					layer = self.__GetEffectiveLayer(aElement)
 					if not layer in self.__MissingBldInfs:
 						self.__MissingBldInfs[layer]=[]