Skip to content
Snippets Groups Projects
Select Git revision
  • b7b50ffb1c15e39a5441e3ecef268fd9580f6c50
  • master default
  • y3
  • y2
  • y1
5 results

ModelParser.py

Blame
  • ModelParser.py 4.96 KiB
    # -------------------------------------------------------------------------
    #		PIACERE ICG Parser
    #
    #       This module has been tested with Python v3.7.4
    #       To use it you must first install PyEcore
    #           $ pip install pyecore
    #
    #       Usage: python icgparser.py [-h] [-d dir] [-v] [--single] model
    #           -h          prints usage
    #           -d dir      loads metamodel from <dir>
    #           --single / --single_mmodel   use the single (non-split) metamodel
    #           model       the input model to be translated into the ICG intermediate representation
    #
    #		© Copyright 2022 Hewlett Packard Enterprise Development LP
    # -------------------------------------------------------------------------
    import logging
    from pyecore.resources import ResourceSet, URI, global_registry
    import pyecore.ecore as Ecore  # This gets a reference to the Ecore metamodel implementation
    
    from icgparser import DomlParserUtilities
    from icgparser.DomlParserUtilities import get_reference_list_if_exists
    
    
    OUTPUT_BASE_DIR_PATH = "output_files_generated/"
    DOML_PATH = "icgparser/doml/doml.ecore"
    
    doml_layers = {
        "active_infrastructure_layer": "activeInfrastructure",
    }
    
    
    def load_model(doml_path, model_path):
        global_registry[Ecore.nsURI] = Ecore  # Load the Ecore metamodel first
        rset = ResourceSet()
        resource = rset.get_resource(URI(f"{doml_path}"))
        mm_root = resource.contents[0]  # Get the root of the MetaModel (EPackage)
        rset.metamodel_registry[mm_root.nsURI] = mm_root
        for subp in mm_root.eSubpackages:
            rset.metamodel_registry[subp.nsURI] = subp
        doml_model_resource = rset.get_resource(URI(model_path))
        return doml_model_resource.contents[0]
    
    
    def to_camel_case(content):
        return content[0].lower() + content[1:]
    
    
    def include_missing_objects_from_infrastructure_layer(to_step):
        for obj_name in DomlParserUtilities.retrieve_missing_parsed_resources():
            obj = DomlParserUtilities.retrieve_missing_parsed_resources()[obj_name]
            infra_object_representation = {}
            infra_object_representation = DomlParserUtilities.save_attributes(obj["resource"], infra_object_representation)
            infra_object_representation = DomlParserUtilities.save_inner_components(obj["resource"],
                                                                                    infra_object_representation)
            ## TODO fix attenzione che sovrascrive
            ir_key_name = to_camel_case(obj["reference"].eType.name)
            to_step["data"][ir_key_name] = [infra_object_representation]
            return to_step
    
    
    def include_infra_object_from_concrete_layer(provider, infra_object_step):
        logging.info(f'Adding objects from concrete layer for provider {provider.name}')
        for ref in provider.eClass.eReferences:
            provider_object_list = get_reference_list_if_exists(provider, ref)
            if provider_object_list:
                logging.info(
                    f'Found list of object {len(provider_object_list)} "{provider_object_list}" in "{provider.name}"')
                object_list_representation = []
                for object in provider_object_list:
                    object_representation = {}
                    object_representation = DomlParserUtilities.save_annotations(object, object_representation)
                    object_representation = DomlParserUtilities.save_attributes(object, object_representation)
                    object_representation = DomlParserUtilities.add_infrastructure_information(object.maps,
                                                                                               object_representation)
                    object_list_representation.append(object_representation)
                infra_object_step["data"][ref.name] = object_list_representation
        return infra_object_step
    
    
    def parse_infrastructural_objects(doml_model):
        infra_object_step = {"programming_language": "terraform"}  ## TODO refactoring: generalize
        concretization_layer = doml_model.eGet(doml_layers["active_infrastructure_layer"])
        providers = concretization_layer.providers
        for provider in providers:
            logging.info(f'Searching objects to be generates for provider "{provider.name}"')
            infra_object_step["data"] = {}  ## TODO refactoring, fix (maybe list?): generalize
            infra_object_step["data"]["provider"] = provider.name  ## TODO refactoring: generalize
            infra_object_step = include_infra_object_from_concrete_layer(provider, infra_object_step)
            infra_object_step = include_missing_objects_from_infrastructure_layer(infra_object_step)
        return infra_object_step
    
    def parse_model(model_path):
        doml_model = load_model(DOML_PATH, model_path)
        model_name = doml_model.name
        output_path = OUTPUT_BASE_DIR_PATH + model_name + "/"
        intermediate_representation_steps = []
        infra_object_step = parse_infrastructural_objects(doml_model)
        intermediate_representation_steps.append(infra_object_step)
        intermediate_representation = {
            "output_path": output_path,
            "steps": intermediate_representation_steps
        }
        return intermediate_representation