1 #!/usr/bin/python2.4 2 # 3 # 4 # Copyright 2008, The Android Open Source Project 5 # 6 # Licensed under the Apache License, Version 2.0 (the "License"); 7 # you may not use this file except in compliance with the License. 8 # You may obtain a copy of the License at 9 # 10 # http://www.apache.org/licenses/LICENSE-2.0 11 # 12 # Unless required by applicable law or agreed to in writing, software 13 # distributed under the License is distributed on an "AS IS" BASIS, 14 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 # See the License for the specific language governing permissions and 16 # limitations under the License. 17 import xml.dom.minidom 18 import xml.parsers 19 import os 20 21 import logger 22 import errors 23 24 class CoverageTargets: 25 """Accessor for the code coverage target xml file 26 Expects the following format: 27 <targets> 28 <target 29 name="" 30 type="JAVA_LIBRARIES|APPS" 31 build_path="" 32 33 [<src path=""/>] (0..*) - These are relative to build_path. If missing, 34 assumes 'src' 35 >/target> 36 37 TODO: add more format checking 38 """ 39 40 _TARGET_TAG_NAME = 'coverage_target' 41 42 def __init__(self, ): 43 self._target_map= {} 44 45 def __iter__(self): 46 return iter(self._target_map.values()) 47 48 def Parse(self, file_path): 49 """Parse the coverage target data from from given file path, and add it to 50 the current object 51 Args: 52 file_path: absolute file path to parse 53 Raises: 54 errors.ParseError if file_path cannot be parsed 55 """ 56 try: 57 doc = xml.dom.minidom.parse(file_path) 58 except IOError: 59 # Error: The results file does not exist 60 logger.Log('Results file %s does not exist' % file_path) 61 raise errors.ParseError 62 except xml.parsers.expat.ExpatError: 63 logger.Log('Error Parsing xml file: %s ' % file_path) 64 raise errors.ParseError 65 66 target_elements = doc.getElementsByTagName(self._TARGET_TAG_NAME) 67 68 for target_element in target_elements: 69 target = CoverageTarget(target_element) 70 self._AddTarget(target) 71 72 def _AddTarget(self, target): 73 self._target_map[target.GetName()] = target 74 75 def GetBuildTargets(self): 76 """ returns list of target names """ 77 build_targets = [] 78 for target in self: 79 build_targets.append(target.GetName()) 80 return build_targets 81 82 def GetTargets(self): 83 """ returns list of CoverageTarget""" 84 return self._target_map.values() 85 86 def GetTarget(self, name): 87 """ returns CoverageTarget for given name. None if not found """ 88 try: 89 return self._target_map[name] 90 except KeyError: 91 return None 92 93 class CoverageTarget: 94 """ Represents one coverage target definition parsed from xml """ 95 96 _NAME_ATTR = 'name' 97 _TYPE_ATTR = 'type' 98 _BUILD_ATTR = 'build_path' 99 _SRC_TAG = 'src' 100 _PATH_ATTR = 'path' 101 102 def __init__(self, target_element): 103 self._name = target_element.getAttribute(self._NAME_ATTR) 104 self._type = target_element.getAttribute(self._TYPE_ATTR) 105 self._build_path = target_element.getAttribute(self._BUILD_ATTR) 106 self._paths = [] 107 self._ParsePaths(target_element) 108 109 def GetName(self): 110 return self._name 111 112 def GetPaths(self): 113 return self._paths 114 115 def GetType(self): 116 return self._type 117 118 def GetBuildPath(self): 119 return self._build_path 120 121 def _ParsePaths(self, target_element): 122 src_elements = target_element.getElementsByTagName(self._SRC_TAG) 123 if len(src_elements) <= 0: 124 # no src tags specified. Assume build_path + src 125 self._paths.append(os.path.join(self.GetBuildPath(), "src")) 126 for src_element in src_elements: 127 rel_path = src_element.getAttribute(self._PATH_ATTR) 128 self._paths.append(os.path.join(self.GetBuildPath(), rel_path)) 129 130 def Parse(xml_file_path): 131 """parses out a file_path class from given path to xml""" 132 targets = CoverageTargets() 133 targets.Parse(xml_file_path) 134 return targets 135