|
| 1 | +import json |
| 2 | +import pathlib |
| 3 | + |
| 4 | +from flamapy.core.transformations.text_to_model import TextToModel |
| 5 | + |
| 6 | +from flamapy.metamodels.configuration_metamodel.models.configuration import Configuration |
| 7 | +from flamapy.core.exceptions import ConfigurationNotFound |
| 8 | + |
| 9 | + |
| 10 | +class UVLSJSONReader(TextToModel): |
| 11 | + """Reads a configuration generated with the UVLS tool from a JSON file or directory |
| 12 | + and transforms it into a Configuration model. |
| 13 | +
|
| 14 | + The JSON file should contain a dictionary where keys are element names (e.g., features) |
| 15 | + and values are the corresponding values for those elements. |
| 16 | + |
| 17 | + The JSON file contains a 'file' and a 'config' key. |
| 18 | + The 'config' key will be used to extract the configuration elements. |
| 19 | + The JSON file can also contain metadata, which will be ignored in the transformation. |
| 20 | + |
| 21 | + If the JSON file is a directory, it will read all JSON files in that directory and concatenate |
| 22 | + their configurations into a single Configuration object. |
| 23 | + This allows for managing multiple configurations associated with variability models split in |
| 24 | + several files (e.g., imports in UVL models). |
| 25 | +
|
| 26 | + If the JSON file or directory does not exist, it raises a ConfigurationNotFound exception. |
| 27 | + """ |
| 28 | + |
| 29 | + @staticmethod |
| 30 | + def get_source_extension() -> str: |
| 31 | + return 'uvl.json' |
| 32 | + |
| 33 | + def __init__(self, path: str) -> None: |
| 34 | + self._path: str = path |
| 35 | + |
| 36 | + def transform(self) -> Configuration: |
| 37 | + path = pathlib.Path(self._path) |
| 38 | + if path.is_file(): |
| 39 | + return self.get_configuration_from_json(path) |
| 40 | + elif path.is_dir(): |
| 41 | + return self.get_configuration_from_directory(path) |
| 42 | + else: |
| 43 | + raise ConfigurationNotFound |
| 44 | + |
| 45 | + def get_configuration_from_json(self, path: pathlib.Path) -> Configuration: |
| 46 | + """Reads a JSON file and returns a Configuration object.""" |
| 47 | + with open(path, 'r', encoding='utf-8') as file: |
| 48 | + json_dict = json.load(file) |
| 49 | + elements = json_dict['config'] |
| 50 | + return Configuration(elements) |
| 51 | + |
| 52 | + def get_configuration_from_directory(self, directory: pathlib.Path) -> Configuration: |
| 53 | + """Reads all JSON files in a directory and returns a Configuration object as |
| 54 | + result of concatenating all configurations.""" |
| 55 | + elements = {} |
| 56 | + for filepath in directory.rglob('*.json'): |
| 57 | + if filepath.is_file(): |
| 58 | + config = self.get_configuration_from_json(filepath) |
| 59 | + elements.update(config.elements) |
| 60 | + return Configuration(elements) |
0 commit comments