#!/usr/bin/python2.4
#
#
# Copyright 2008, The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import xml.dom.minidom
import xml.parsers
import os
import coverage_target
import logger
import errors
class CoverageTargets:
"""Accessor for the code coverage target xml file
Expects the following format:
<targets>
<target
name=""
type="JAVA_LIBRARIES|APPS"
build_path=""
[<src path=""/>] (0..*) - These are relative to build_path. If missing,
assumes 'src'
>/target>
TODO: add more format checking
"""
_TARGET_TAG_NAME = 'coverage_target'
_NAME_ATTR = 'name'
_TYPE_ATTR = 'type'
_BUILD_ATTR = 'build_path'
_SRC_TAG = 'src'
_PATH_ATTR = 'path'
def __init__(self, ):
self._target_map= {}
def __iter__(self):
return iter(self._target_map.values())
def Parse(self, file_path):
"""Parse the coverage target data from from given file path, and add it to
the current object
Args:
file_path: absolute file path to parse
Raises:
errors.ParseError if file_path cannot be parsed
"""
try:
doc = xml.dom.minidom.parse(file_path)
except IOError:
# Error: The results file does not exist
logger.Log('Results file %s does not exist' % file_path)
raise errors.ParseError
except xml.parsers.expat.ExpatError:
logger.Log('Error Parsing xml file: %s ' % file_path)
raise errors.ParseError
target_elements = doc.getElementsByTagName(self._TARGET_TAG_NAME)
for target_element in target_elements:
target = coverage_target.CoverageTarget()
self._ParseCoverageTarget(target, target_element)
self._AddTarget(target)
def _AddTarget(self, target):
self._target_map[target.GetName()] = target
def GetBuildTargets(self):
""" returns list of target names """
build_targets = []
for target in self:
build_targets.append(target.GetName())
return build_targets
def GetTargets(self):
""" returns list of CoverageTarget"""
return self._target_map.values()
def GetTarget(self, name):
""" returns CoverageTarget for given name. None if not found """
try:
return self._target_map[name]
except KeyError:
return None
def _ParseCoverageTarget(self, target, target_element):
"""Parse coverage data from XML.
Args:
target: the Coverage object to populate
target_element: the XML element to get data from
"""
target.SetName(target_element.getAttribute(self._NAME_ATTR))
target.SetType(target_element.getAttribute(self._TYPE_ATTR))
target.SetBuildPath(target_element.getAttribute(self._BUILD_ATTR))
self._paths = []
self._ParsePaths(target, target_element)
def _ParsePaths(self, target, target_element):
src_elements = target_element.getElementsByTagName(self._SRC_TAG)
if len(src_elements) <= 0:
# no src tags specified. Assume build_path + src
target.AddPath(os.path.join(target.GetBuildPath(), "src"))
for src_element in src_elements:
rel_path = src_element.getAttribute(self._PATH_ATTR)
target.AddPath(os.path.join(target.GetBuildPath(), rel_path))
def Parse(xml_file_path):
"""parses out a file_path class from given path to xml"""
targets = CoverageTargets()
targets.Parse(xml_file_path)
return targets