import os
import json
import sys
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
from sort_sa_by_bootphase import SARearrangement
import sa_info_config_errors as json_err
class JsonSAInfoMerger(object):
class SAInfoCollector(object):
"""
Class for collecting sa info pieces shared with same process name
"""
def __init__(self, process_name, wdir):
self.process_name = process_name
self.systemabilities = []
self.wdir = wdir
@property
def output_filename(self):
basename = self.process_name + '.json'
return os.path.join(self.wdir, basename)
def add_systemability_info(self, systemability):
self.systemabilities += systemability
def merge_sa_info(self):
"""
Write all pieces of sa info shared with same process to a new file
"""
xml_lines = {}
xml_lines['process'] = self.process_name
xml_lines['systemability'] = self.systemabilities
if not os.path.exists(self.wdir):
os.mkdir(self.wdir)
with os.fdopen(os.open(self.output_filename, os.O_RDWR | os.O_CREAT | os.O_TRUNC, 0o640), 'w') as json_files:
json.dump(xml_lines, json_files, indent=4, ensure_ascii=False)
def __init__(self):
self.process_sas_dict = {}
self.output_filelist = []
def add_to_output_filelist(self, infile: str):
self.output_filelist.append(os.path.join(self.output_dir, infile))
def merge(self, sa_info_filelist, output_dir):
return self.__merge(sa_info_filelist, output_dir)
def parse_json_file(self, file: str):
with open(file, 'r') as json_files:
data = json.load(json_files)
_format = 'one and only one {} tag is expected, actually {} is found'
if 'process' not in data or data['process'] == '':
raise json_err.BadFormatJsonError('provide a valid value for process', file)
process_name = data['process']
if self.process_sas_dict.get(process_name) is None:
sa_info_collector = self.SAInfoCollector(process_name, self.temp_dir)
self.process_sas_dict[process_name] = sa_info_collector
self.add_to_output_filelist(process_name + '.json')
else:
sa_info_collector = self.process_sas_dict.get(process_name)
if 'systemability' not in data or data['systemability'] == '':
raise json_err.BadFormatJsonError('provide a valid value for systemability', file)
sys_count = len(data['systemability'])
if sys_count != 1:
raise json_err.BadFormatJsonError(_format.format('systemabiltiy', sys_count), file)
sys_value = data['systemability']
if 'name' not in sys_value[0] or 'libpath' not in sys_value[0]:
raise json_err.BadFormatJsonError('systemability must have name and libpath', file)
sa_info_collector.add_systemability_info(sys_value)
def __merge(self, sa_info_filelist: list, path_merges: str):
"""
merge the json files of sa_info_filelist
:param sa_info_filelist : input_files
:param path_merges : merges_path
"""
self.temp_dir = path_merges
self.output_dir = path_merges
for file in sa_info_filelist:
self.parse_json_file(file)
global_ordered_systemability_names = []
global_systemability_deps_dict = {}
for process, collector in self.process_sas_dict.items():
rearragement = SARearrangement()
collector.merge_sa_info()
merged_file = collector.output_filename
rearragement.sort(merged_file, merged_file)
deps_info = rearragement.get_deps_info()
global_ordered_systemability_names += deps_info[0]
global_systemability_deps_dict.update(deps_info[1])
try:
SARearrangement.detect_invalid_dependency_globally(
global_ordered_systemability_names,
global_systemability_deps_dict)
except json_err.CircularDependencyError as error:
for _file in self.output_filelist:
try:
os.remove(_file)
except OSError:
pass
raise json_err.CrossProcessCircularDependencyError(error)
return self.output_filelist