142 |
142 |
143 class SystemModelComponent(generic_path.Path): |
143 class SystemModelComponent(generic_path.Path): |
144 """Path sub-class that wraps up a component bld.inf file with |
144 """Path sub-class that wraps up a component bld.inf file with |
145 system_definition.xml context information.""" |
145 system_definition.xml context information.""" |
146 |
146 |
147 def __init__(self, aBldInfFile, aContainerNames, aSystemDefinitionFile, aSystemDefinitionBase, aSystemDefinitionVersion): |
147 def __init__(self, aBldInfFile, aLayerName, aContainerNames, aSystemDefinitionFile, aSystemDefinitionBase, aSystemDefinitionVersion): |
148 generic_path.Path.__init__(self, aBldInfFile.Absolute().path) |
148 generic_path.Path.__init__(self, aBldInfFile.Absolute().path) |
149 self.__ContainerNames = aContainerNames |
149 self.__ContainerNames = aContainerNames |
|
150 self.__LayerName = aLayerName |
150 self.__SystemDefinitionFile = aSystemDefinitionFile |
151 self.__SystemDefinitionFile = aSystemDefinitionFile |
151 self.__SystemDefinitionBase = aSystemDefinitionBase |
152 self.__SystemDefinitionBase = aSystemDefinitionBase |
152 self.__SystemDefinitionVersion = aSystemDefinitionVersion |
153 self.__SystemDefinitionVersion = aSystemDefinitionVersion |
153 |
154 |
154 def GetSystemDefinitionFile(self): |
155 def GetSystemDefinitionFile(self): |
261 self.__Version['MID'] = int(version.group('MID')) |
266 self.__Version['MID'] = int(version.group('MID')) |
262 self.__Version['MINOR'] = int(version.group('MINOR')) |
267 self.__Version['MINOR'] = int(version.group('MINOR')) |
263 |
268 |
264 if self.__Version['MAJOR'] == 1 and self.__Version['MID'] > 2: |
269 if self.__Version['MAJOR'] == 1 and self.__Version['MID'] > 2: |
265 self.__ComponentRoot = self.__SystemDefinitionBase |
270 self.__ComponentRoot = self.__SystemDefinitionBase |
266 elif self.__Version['MAJOR'] == 2: |
271 elif self.__Version['MAJOR'] == 2 or self.__Version['MAJOR'] == 3: |
267 # 2.0.0 format supports SOURCEROOT as an environment specified base - we respect this, unless |
272 # 2.0.x and 3.0.0 formats support SOURCEROOT or SRCROOT as an environment specified base - we respect this, unless |
268 # explicitly overridden on the command line |
273 # explicitly overridden on the command line |
269 if os.environ.has_key('SOURCEROOT'): |
274 if os.environ.has_key('SRCROOT'): |
|
275 self.__ComponentRoot = generic_path.Path(os.environ['SRCROOT']) |
|
276 elif os.environ.has_key('SOURCEROOT'): |
270 self.__ComponentRoot = generic_path.Path(os.environ['SOURCEROOT']) |
277 self.__ComponentRoot = generic_path.Path(os.environ['SOURCEROOT']) |
|
278 |
271 if self.__SystemDefinitionBase and self.__SystemDefinitionBase != ".": |
279 if self.__SystemDefinitionBase and self.__SystemDefinitionBase != ".": |
272 self.__ComponentRoot = self.__SystemDefinitionBase |
280 self.__ComponentRoot = self.__SystemDefinitionBase |
273 if os.environ.has_key('SOURCEROOT'): |
281 if os.environ.has_key('SRCROOT'): |
|
282 self.__Logger.Info("Command line specified System Definition file base \'%s\' overriding environment SRCROOT \'%s\'", self.__SystemDefinitionBase, os.environ['SRCROOT']) |
|
283 elif os.environ.has_key('SOURCEROOT'): |
274 self.__Logger.Info("Command line specified System Definition file base \'%s\' overriding environment SOURCEROOT \'%s\'", self.__SystemDefinitionBase, os.environ['SOURCEROOT']) |
284 self.__Logger.Info("Command line specified System Definition file base \'%s\' overriding environment SOURCEROOT \'%s\'", self.__SystemDefinitionBase, os.environ['SOURCEROOT']) |
275 else: |
285 else: |
276 self.__Logger.Error("Cannot process schema version %s of file %s", version.string, self.__SystemDefinitionFile) |
286 self.__Logger.Error("Cannot process schema version %s of file %s", version.string, self.__SystemDefinitionFile) |
277 return False |
287 return False |
278 |
288 |
|
289 if self.__Version['MAJOR'] >= 3: |
|
290 # id is the unique identifier for 3.0 and later schema |
|
291 self.__IdAttribute = "id" |
|
292 |
279 return True |
293 return True |
280 |
294 |
281 def __Parse(self): |
295 def __Parse(self): |
282 # find the <systemModel> element (there can be 0 or 1) and search any <layer> elements for <unit> elements with "bldFile" attributes |
296 # For 2.0 and earlier: find the <systemModel> element (there can be 0 or 1) and search any <layer> elements for <unit> elements with "bldFile" attributes |
283 # the <layer> context of captured "bldFile" attributes is recorded as we go |
297 # the <layer> context of captured "bldFile" attributes is recorded as we go |
|
298 # For 3.0 and later, process any architectural topmost element, use the topmost element with an id as the "layer" |
284 for child in self.__SystemDefinitionElement.childNodes: |
299 for child in self.__SystemDefinitionElement.childNodes: |
285 if child.localName == "systemModel": |
300 if child.localName == "systemModel" or child.localName == "layer" or child.localName == "package" or child.localName == "collection" or child.localName == "component": |
286 self.__ProcessSystemModelElement(child) |
301 self.__ProcessSystemModelElement(child) |
287 |
302 |
288 def __CreateComponent(self, aBldInfFile, aUnitElement): |
303 def __CreateComponent(self, aBldInfFile, aUnitElement): |
289 # take a resolved bld.inf file and associated <unit/> element and returns a populated Component object |
304 # take a resolved bld.inf file and associated <unit/> element and returns a populated Component object |
290 containers = {} |
305 containers = {} |
291 self.__GetElementContainers(aUnitElement, containers) |
306 self.__GetElementContainers(aUnitElement, containers) |
292 component = SystemModelComponent(aBldInfFile, containers, self.__SystemDefinitionFile, self.__SystemDefinitionBase, self.__Version) |
307 layer = self.__GetEffectiveLayer(aUnitElement) |
|
308 component = SystemModelComponent(aBldInfFile, layer, containers, self.__SystemDefinitionFile, self.__SystemDefinitionBase, self.__Version) |
293 |
309 |
294 return component |
310 return component |
|
311 |
|
312 def __GetEffectiveLayer(self, aElement): |
|
313 #' return the ID of the topmost item which has an ID. For 1.x and 2.x, this will always be layer, for 3.x, it will be the topmost ID'd element in the file |
|
314 # never call this on the root element |
|
315 if aElement.parentNode.hasAttribute(self.__IdAttribute): |
|
316 return self.__GetEffectiveLayer(aElement.parentNode) |
|
317 elif aElement.hasAttribute(self.__IdAttribute): |
|
318 return aElement.getAttribute(self.__IdAttribute) |
|
319 return "" |
295 |
320 |
296 def __GetElementContainers(self, aElement, aContainers): |
321 def __GetElementContainers(self, aElement, aContainers): |
297 # take a <unit/> element and creates a type->name dictionary of all of its parent containers |
322 # take a <unit/> element and creates a type->name dictionary of all of its parent containers |
298 # We're only interested in parent nodes if they're not the top-most node |
323 # We're only interested in parent nodes if they're not the top-most node |
299 if aElement.parentNode.parentNode: |
324 if aElement.parentNode.parentNode: |
300 parent = aElement.parentNode |
325 parent = aElement.parentNode |
301 name = parent.getAttribute("name") |
326 name = parent.getAttribute(self.__IdAttribute) |
302 |
327 |
303 if name: |
328 if name: |
304 aContainers[parent.tagName] = name |
329 aContainers[parent.tagName] = name |
305 |
330 |
306 self.__GetElementContainers(parent, aContainers) |
331 self.__GetElementContainers(parent, aContainers) |
307 |
332 |
308 def __ProcessSystemModelElement(self, aElement): |
333 def __ProcessSystemModelElement(self, aElement): |
309 """Search for XML <unit/> elements with 'bldFile' attributes and resolve concrete bld.inf locations |
334 """Search for XML <unit/> elements with 'bldFile' attributes and resolve concrete bld.inf locations |
310 with an appreciation of different schema versions.""" |
335 with an appreciation of different schema versions.""" |
311 |
336 |
312 if aElement.tagName == "layer": |
337 # The effective "layer" is the item whose parent does not have an id (or name in 2.x and earlier) |
313 currentLayer = aElement.getAttribute("name") |
338 if not aElement.parentNode.hasAttribute(self.__IdAttribute) : |
|
339 currentLayer = aElement.getAttribute(self.__IdAttribute) |
314 |
340 |
315 if not self.__LayerDetails.has_key(currentLayer): |
341 if not self.__LayerDetails.has_key(currentLayer): |
316 self.__LayerDetails[currentLayer] = [] |
342 self.__LayerDetails[currentLayer] = [] |
317 |
343 |
318 if not currentLayer in self.__LayerList: |
344 if not currentLayer in self.__LayerList: |
340 self.__Logger.Error("Cannot resolve \'root\' attribute value \"%s\" in %s", rootValue, self.__SystemDefinitionFile) |
366 self.__Logger.Error("Cannot resolve \'root\' attribute value \"%s\" in %s", rootValue, self.__SystemDefinitionFile) |
341 return |
367 return |
342 |
368 |
343 group = generic_path.Path(bldFileValue) |
369 group = generic_path.Path(bldFileValue) |
344 |
370 |
345 if not group.isAbsolute() and bldInfRoot: |
371 if self.__Version['MAJOR'] < 3: |
346 group = generic_path.Join(bldInfRoot, group) |
372 # absolute paths are not changed by root var in 1.x and 2.x |
|
373 if not group.isAbsolute() and bldInfRoot: |
|
374 group = generic_path.Join(bldInfRoot, group) |
|
375 else: |
|
376 # only absolute paths are changed by root var in 3.x |
|
377 if group.isAbsolute() and bldInfRoot: |
|
378 group = generic_path.Join(bldInfRoot, group) |
347 |
379 |
348 bldinf = generic_path.Join(group, "bld.inf").FindCaseless() |
380 bldinf = generic_path.Join(group, "bld.inf").FindCaseless() |
349 |
381 |
350 if bldinf == None: |
382 if bldinf == None: |
351 self.__Logger.Error("No bld.inf found at %s in %s", group.GetLocalString(), self.__SystemDefinitionFile) |
383 self.__Logger.Error("No bld.inf found at %s in %s", group.GetLocalString(), self.__SystemDefinitionFile) |
352 else: |
384 else: |
353 component = self.__CreateComponent(bldinf, aElement) |
385 component = self.__CreateComponent(bldinf, aElement) |
354 layer = component.GetContainerName("layer") |
386 layer = component.GetLayerName() |
355 if layer: |
387 if layer: |
356 self.__LayerDetails[layer].append(component) |
388 self.__LayerDetails[layer].append(component) |
357 self.__TotalComponents += 1 |
389 self.__TotalComponents += 1 |
358 else: |
390 else: |
359 self.__Logger.Error("No containing layer found for %s in %s", str(bldinf), self.__SystemDefinitionFile) |
391 self.__Logger.Error("No containing layer found for %s in %s", str(bldinf), self.__SystemDefinitionFile) |