sbsv2/raptor/python/raptor_cache.py
changeset 0 044383f39525
child 3 e1eecf4d390d
child 590 360bd6b35136
equal deleted inserted replaced
-1:000000000000 0:044383f39525
       
     1 #
       
     2 # Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 # All rights reserved.
       
     4 # This component and the accompanying materials are made available
       
     5 # under the terms of the License "Eclipse Public License v1.0"
       
     6 # which accompanies this distribution, and is available
       
     7 # at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 #
       
     9 # Initial Contributors:
       
    10 # Nokia Corporation - initial contribution.
       
    11 #
       
    12 # Contributors:
       
    13 #
       
    14 # Description: 
       
    15 # raptor_cache module
       
    16 # This module represents a cache of objects for a Raptor program.
       
    17 #
       
    18 
       
    19 import raptor_data
       
    20 import raptor_xml
       
    21 import generic_path
       
    22 import os
       
    23 
       
    24 # raptor_cache module attributes
       
    25 
       
    26 
       
    27 # raptor_cache module classes
       
    28 
       
    29 class Cache:
       
    30 
       
    31 	def __init__(self, Raptor):
       
    32 		self.raptor = Raptor
       
    33 		self.aliases = {}
       
    34 		self.groups = {}
       
    35 		self.interfaces = {}
       
    36 		self.variants = {}
       
    37 
       
    38 	def Load(self, gPathOrGPathList, cacheID = ""):
       
    39 		"""scan directory for xml files containing Raptor objects.
       
    40 		Input is either a generic path object or a list of
       
    41 		generic path objects.
       
    42 
       
    43 		If a cacheID is supplied then the loaded objects are
       
    44 		placed into containers which are marked with that ID.
       
    45 		This is useful for Interfaces which may be loaded from
       
    46 		several locations (different epoc32 trees for example)
       
    47 		but need to be kept separate.
       
    48 		"""
       
    49 
       
    50 		pathlist = []
       
    51 		filenames = []
       
    52 
       
    53 		# Create pathlist - this will be of length one if gPathOrGPathList is a
       
    54 		# generic path object; otherwise it's a list so just make all supplied paths generic
       
    55 		if isinstance(gPathOrGPathList, list):
       
    56 			pathlist = map(lambda x: x.GetLocalString(), gPathOrGPathList)
       
    57 		elif isinstance(gPathOrGPathList, generic_path.Path):
       
    58 			pathlist = [gPathOrGPathList.GetLocalString()]
       
    59 		else:
       
    60 			self.raptor.Warn("Empty list or blank path supplied.")
       
    61 
       
    62 		# Only when debugging, print the list. The for loop will be
       
    63 		# skipped if not in debug mode
       
    64 		if self.raptor.debugOutput:
       
    65 			for path in pathlist:
       
    66 				self.raptor.Debug("Loading XML cache from %s", path)
       
    67 
       
    68 		# Internal function to get the list of XML
       
    69 		# files recursively
       
    70 		def getXmlFiles(aDir, aFileList):
       
    71 			dirList = []
       
    72 			for fname in os.listdir(aDir):
       
    73 				path = os.path.join(aDir, fname)
       
    74 				if os.path.isdir(path):
       
    75 					dirList.append(path)
       
    76 				else: # It's a file
       
    77 					if path.endswith(".xml"): # Only files ending in .xml get added
       
    78 						aFileList.append(path)
       
    79 			# Now iterate over directory list; this way, the files in the top level of
       
    80 			# aDir will be added before all files in any subdirectory of aDir
       
    81 			for dir in dirList:
       
    82 				getXmlFiles(dir, aFileList)
       
    83 
       
    84 		# This will add all files in all top level directories and all XML files
       
    85 		for path in pathlist:
       
    86 			# gPathOrGPathList passed to Load() can be a file or a
       
    87 			# directory, or a list of files or directories or both
       
    88 			if os.path.isfile(path):
       
    89 				if path.endswith(".xml"): # Only files whose names end in .xml get added
       
    90 					filenames.append(path)
       
    91 			elif os.path.isdir(path):
       
    92 				getXmlFiles(path, filenames)
       
    93 			else: # it isn't a file or directory
       
    94 				self.raptor.Warn("No file or directory found for '%s'", path)
       
    95 
       
    96 		if not filenames:
       
    97 			# No XML files found in any of the paths
       
    98 			return
       
    99 
       
   100 		# Parse XML files, and add the objects to our
       
   101 		# configuration/interface/variant dictionaries
       
   102 		for fullpath in filenames:
       
   103 			try:
       
   104 				objects = raptor_xml.Read(self.raptor, fullpath)
       
   105 
       
   106 			except raptor_xml.XMLError:
       
   107 				self.raptor.Warn("Failed to read XML file %s", fullpath)
       
   108 				continue
       
   109 
       
   110 			self.raptor.Debug("%d objects found in XML file %s", len(objects), fullpath)
       
   111 
       
   112 			for obj in objects:
       
   113 				# top-level objects need to know which XML file they came from.
       
   114 				obj.SetSourceFile(fullpath)
       
   115 				try:
       
   116 					self.AddObject(obj, cacheID)
       
   117 				except UnexpectedObjectError:
       
   118 					self.raptor.Warn("Unexpected object %s", str(obj))
       
   119 
       
   120 	def AddObject(self, obj, cacheID):
       
   121 		"""add a Group, Alias, Interface or Variant.
       
   122 
       
   123 		The cacheID is only used to separate Interfaces.
       
   124 		"""
       
   125 
       
   126 		if isinstance(obj, raptor_data.Group):
       
   127 			self.AddGroup(obj)
       
   128 		elif isinstance(obj, raptor_data.Alias):
       
   129 			self.AddAlias(obj)
       
   130 		elif isinstance(obj, raptor_data.Interface):
       
   131 			self.AddInterface(obj, cacheID)
       
   132 		elif isinstance(obj, raptor_data.Variant):
       
   133 			self.AddVariant(obj)
       
   134 		else:
       
   135 			raise UnexpectedObjectError
       
   136 
       
   137 
       
   138 	def FindNamedGroup(self, name):
       
   139 		return self.groups[name]
       
   140 
       
   141 	def AddGroup(self, obj):
       
   142 		if obj.name in self.groups:
       
   143 			self.WarnDuplicate("group", self.groups[obj.name], obj)
       
   144 			return
       
   145 
       
   146 		obj.SetOwner(self.raptor)
       
   147 		self.groups[obj.name] = obj
       
   148 
       
   149 	def FindNamedAlias(self, name):
       
   150 		return self.aliases[name]
       
   151 
       
   152 	def AddAlias(self, obj):
       
   153 		if obj.name in self.aliases:
       
   154 			self.WarnDuplicate("alias", self.aliases[obj.name], obj)
       
   155 			return
       
   156 
       
   157 		obj.SetOwner(self.raptor)
       
   158 		self.aliases[obj.name] = obj
       
   159 
       
   160 
       
   161 	def FindNamedInterface(self, name, cacheID = ""):
       
   162 		try:
       
   163 			return self.interfaces[cacheID][name]
       
   164 		except KeyError, e:
       
   165 			if cacheID == "":
       
   166 				raise e
       
   167 			else:
       
   168 				return self.interfaces[""][name]
       
   169 
       
   170 
       
   171 	def AddInterface(self, obj, cacheID):
       
   172 		if not cacheID in self.interfaces:
       
   173 			self.interfaces[cacheID] = {}
       
   174 
       
   175 		if obj.name in self.interfaces[cacheID]:
       
   176 			self.WarnDuplicate("interface", self.interfaces[cacheID][obj.name], obj)
       
   177 			return
       
   178 
       
   179 		obj.SetOwner(self.raptor)
       
   180 		obj.cacheID = cacheID
       
   181 		self.interfaces[cacheID][obj.name] = obj
       
   182 
       
   183 
       
   184 	def FindNamedVariant(self, name):
       
   185 		return self.variants[name]
       
   186 
       
   187 
       
   188 	def AddVariant(self, obj):
       
   189 		# anonymous variants can never be referenced, so ignore them
       
   190 		if obj.name:
       
   191 			if self.variants.has_key(obj.name):
       
   192 				self.WarnDuplicate("variant", self.variants[obj.name], obj)
       
   193 				return
       
   194 
       
   195 			obj.SetOwner(self.raptor)
       
   196 			self.variants[obj.name] = obj
       
   197 
       
   198 
       
   199 	def WarnDuplicate(self, type, objOld, objNew):
       
   200 		"""tell us where duplicate objects came from."""
       
   201 		oldSource = objOld.source
       
   202 		if oldSource == None:
       
   203 			oldSource = "unknown"
       
   204 
       
   205 		newSource = objNew.source
       
   206 		if newSource == None:
       
   207 			newSource = "unknown"
       
   208 
       
   209 		# don't warn if we are reloading the object from the same
       
   210 		# file as before: since that is quite ligitimate.
       
   211 		if oldSource == newSource and oldSource != "unknown":
       
   212 			return
       
   213 
       
   214 		# actually this is just for information not a warning
       
   215 		self.raptor.Info("Duplicate %s '%s' (the one from '%s' will override the one in '%s')",
       
   216 						 type, objOld.name, oldSource, newSource)
       
   217 
       
   218 
       
   219 class UnexpectedObjectError(Exception):
       
   220 	pass
       
   221 
       
   222 
       
   223 # end of the raptor_cache module