acrn-hypervisor/misc/config_tools/scenario_config/default_populator.py
Weiyi-Feng 06b942f5eb config_tools: Add vue-json-schema-form and advanced custom component for IVSHMEM field
1. add Vue devtools support
2. update project dependencies
3. refactor configurator source code tree for private library hook
4. fix build issue
5. dynamic load scenario JSON schema(fix cache issue)
6. add vjsf 1.12.2 (latest) for private package dependencies
7. remove vjsf unnecessary files
8. use private vjsf as configurator dependencies
9. Add custom IVSHMEM_REGION widget
10. add a script to populate default values
11. get default values before export scenario xml
12. specify widgets in XML schema
13. add missing vjsf license file
14. populate default values to empty nodes
15. when user clicks save button, update formData with each field default value
16. fix when the user clicks the save button will collapse configFom
17. add success message for saving scenario XML

vue-json-schema-form 1.12.2 (latest)link: b30ea7c2d6/packages/lib

Tracked-On: #6691
Signed-off-by: Weiyi Feng <weiyix.feng@intel.com>
2022-05-08 15:52:28 +08:00

103 lines
4.1 KiB
Python
Executable File

#!/usr/bin/env python3
#
# Copyright (C) 2022 Intel Corporation.
#
# SPDX-License-Identifier: BSD-3-Clause
#
import os
import argparse
import elementpath
from scenario_transformer import ScenarioTransformer
from pipeline import PipelineObject, PipelineStage, PipelineEngine
from schema_slicer import SlicingSchemaByVMTypeStage
class DefaultValuePopulator(ScenarioTransformer):
def get_default_value(self, xsd_element_node, xml_parent_node):
# The attribute @default of the xsd:element node
v = xsd_element_node.get("default")
if v is not None:
return v
# The acrn:defaults and acrn:unique-among annotations which define a set of default values that shall be unique
# among a collection of nodes
annot_node = self.get_node(xsd_element_node, "xs:annotation")
if annot_node is not None:
defaults = annot_node.get("{https://projectacrn.org}defaults")
unique_among = annot_node.get("{https://projectacrn.org}unique-among")
if defaults is not None and unique_among is not None:
try:
default_values = set(eval(defaults))
existing_values = set(elementpath.select(self.xml_etree, unique_among, variables={"parent": xml_parent_node}))
available_defaults = default_values - existing_values
return sorted(list(available_defaults))[0]
except:
pass
return None
def add_missing_nodes(self, xsd_element_node, xml_parent_node, new_node_index):
element_name = xsd_element_node.get("name")
default_value = self.get_default_value(xsd_element_node, xml_parent_node)
# If the node is neither of a complex type (i.e. it does not have an child node) nor has a default value, do not
# create the node at all. Users are required to fill in proper values in such nodes, and missing any of them
# shall trigger a validation error.
if self.complex_type_of_element(xsd_element_node) is None and default_value is None:
return []
new_node = xml_parent_node.makeelement(element_name, {})
new_node.text = default_value
if new_node_index is not None:
xml_parent_node.insert(new_node_index, new_node)
else:
xml_parent_node.append(new_node)
return [new_node]
def fill_empty_node(self, xsd_element_node, xml_parent_node, xml_empty_node):
default_value = self.get_default_value(xsd_element_node, xml_parent_node)
if default_value is not None:
xml_empty_node.text = default_value
class DefaultValuePopulatingStage(PipelineStage):
uses = {"schema_etree", "scenario_etree"}
provides = {"scenario_etree"}
def run(self, obj):
populator = DefaultValuePopulator(obj.get("schema_etree"))
etree = obj.get("scenario_etree")
populator.transform(etree)
obj.set("scenario_etree", etree)
def main(args):
from xml_loader import XMLLoadStage
from lxml_loader import LXMLLoadStage
pipeline = PipelineEngine(["schema_path", "scenario_path"])
pipeline.add_stages([
LXMLLoadStage("schema"),
XMLLoadStage("scenario"),
SlicingSchemaByVMTypeStage(),
DefaultValuePopulatingStage(),
])
obj = PipelineObject(schema_path = args.schema, scenario_path = args.scenario)
pipeline.run(obj)
obj.get("scenario_etree").write(args.out)
if __name__ == "__main__":
config_tools_dir = os.path.join(os.path.dirname(__file__), "..")
schema_dir = os.path.join(config_tools_dir, "schema")
parser = argparse.ArgumentParser(description="Populate a given scenario XML with default values of nonexistent nodes")
parser.add_argument("scenario", help="Path to the scenario XML file from users")
parser.add_argument("out", nargs="?", default="out.xml", help="Path where the output is placed")
parser.add_argument("--schema", default=os.path.join(schema_dir, "config.xsd"), help="the XML schema that defines the syntax of scenario XMLs")
args = parser.parse_args()
main(args)