|
1 | | -# UVL - Universal Variability Language Java Metamodel |
2 | | -This is a small default library used to manipulate UVL metamodels in JAVA |
| 1 | +# UVL - Universal Variability Language Java Feature Model Metamodel |
3 | 2 |
|
4 | | -## The Language |
| 3 | +This is a small default library used to manipulate UVL metamodels in JAVA. It uses the [UVL-Grammar](https://github.com/Universal-Variability-Language/) to parse the a given metamodel. If parsed the model can be modified in JAVA. It is possible to also convert the models to different levels. |
5 | 4 |
|
6 | | -On a high level, each feature model in UVL consists of five optional separated elements: |
| 5 | +**How to use UVL** can be found in this paper |
| 6 | +[](https://doi.org/10.1016/j.jss.2024.112326) |
7 | 7 |
|
8 | | -1. **A list of used language levels** |
9 | | -The model can use different concepts which are part of language levels. These levels can either be enumerated with the `include` keyword or be implicit. |
10 | | -2. **A namespace which can be used for references in other models** |
11 | | -3. **A list of imports that can be used to reference external feature models** |
12 | | -The models are referenced by their file name and can be given an alias using a Java import like syntax. |
13 | | -External models in subdirectories can be referenced like this: subdir.filename as fn |
14 | | -4. **The tree hierarchy consisting of: features, group types, and attributes whose relations are specified using nesting (indentation)** |
15 | | -Groups may have an arbitrary number of features as child nodes. A feature can also have a feature cardinality. |
16 | | -Attributes consist of a key-value pair whose key is always a string and its value may be a boolean, number, string, a list attributes, a vector, or a constraint. If the value is a constraint the key must be `constraint`. If the value is a list of constraints the key must be `constraints` |
17 | | -5. **Cross-tree constraints** |
18 | | -Cross-tree constraints may be arbitrary propositional formulas with the following symbols: => (implies), <=> (iff), & (and), | (or), ! (not), or brackets. Through the usage of language levels cross-tree constraints can also contain equations (<,>,==) which consist of expressions (+,-,*,/) with numbers or numerical feature attributes as literals and aggregate functions (avg, sum). |
| 8 | +## ✨ Key Features |
19 | 9 |
|
20 | | -The following snippet shows a simplified server architecture in UVL. We provide more examples (e.g., to show the composition mechanism) in [https://github.com/Universal-Variability-Language/uvl-models/tree/main/Feature_Models](https://github.com/Universal-Variability-Language/uvl-models/tree/main/Feature_Models). |
| 10 | +- full support of UVL-Syntax (namespaces, feature hierarchies and constraints) |
| 11 | +- convert between different language levels |
| 12 | +- direct access to feature model components like features, groups and attributes |
21 | 13 |
|
| 14 | +## ⚙️ Setup |
| 15 | + |
| 16 | +To clone this repository **with all submodules**, use: |
| 17 | + |
| 18 | +```bash |
| 19 | +git clone --recurse-submodules https://github.com/Universal-Variability-Language/java-fm-metamodel.git |
22 | 20 | ``` |
23 | | -namespace Server |
24 | | -
|
25 | | -features |
26 | | - Server {abstract} |
27 | | - mandatory |
28 | | - FileSystem |
29 | | - or // with cardinality: [1..*] |
30 | | - NTFS |
31 | | - APFS |
32 | | - EXT4 |
33 | | - OperatingSystem {abstract} |
34 | | - alternative |
35 | | - Windows |
36 | | - macOS |
37 | | - Debian |
38 | | - optional |
39 | | - Logging { |
40 | | - default, |
41 | | - log_level "warn" // Feature Attribute |
42 | | - } |
43 | | -
|
44 | | -constraints |
45 | | - Windows => NTFS |
46 | | - macOS => APFS |
| 21 | + |
| 22 | +If you have already cloned the repository **without** submodules, you can initialize and update them afterwards with: |
| 23 | + |
| 24 | +```bash |
| 25 | +git submodule update --init --recursive |
47 | 26 | ``` |
48 | 27 |
|
49 | | -In this snippet, we can recognize the following elements: |
50 | | -* The feature `Server` is abstract (i.e., corresponds to no implementation artifact. |
51 | | -* Each `Server` requires a `FileSystem`and an `OperatingSystem` denoted by the *mandatory* group |
52 | | -* The `Server` may have `Logging` denoted by the *optional* group |
53 | | -* A `FileSystem` requires at least one type of `NTFS`, `APFS`, and `Ext4` denoted by the *or* group |
54 | | -* An `OperatingSystem` has exactly one type of `Windows`, `macOS`, and `Debian`denoted by the *alternative* group |
55 | | -* `Logging` has the feature attribute `log_level` attached which is set to "warn" |
56 | | -* `Windows` requires `NTFS` denoted by the first cross-tree constraint |
57 | | -* `macOS`requires `APFS` |
| 28 | +This ensures that all required submodules (e.g., test resources) are available and the project will build and test correctly |
| 29 | + |
| 30 | +## 💡 Usage |
| 31 | + |
| 32 | +### 📦 Getting Started |
58 | 33 |
|
59 | | -## Building a jar |
| 34 | +First, **clone this repository** to your local machine as explained in `⚙️ Setup`. |
| 35 | +To use the Java-fm-metamodel, make sure you are in the project directory before running any further commands. Build the project with [Maven](https://maven.apache.org/): |
60 | 36 |
|
61 | | -The library is a maven project and can therefore be build with maven. To update the generated parser classes and create a jar with all necessary dependencies, use: |
| 37 | +```bash |
| 38 | +mvn clean compile |
62 | 39 | ``` |
63 | | -mvn clean compile assembly:single |
| 40 | + |
| 41 | +This will compile all sources and ensure all dependencies (including submodules) are available. |
| 42 | +Now you can execute code for manipulating UVL feature models as shown in the `Examples` below |
| 43 | + |
| 44 | +### 🧩 Using as a Maven Dependency |
| 45 | + |
| 46 | +You can also use the Java-fm-metamodel as a dependency in your own Maven project. |
| 47 | +Add the following to your `pom.xml`: |
| 48 | + |
| 49 | +```xml |
| 50 | +<dependency> |
| 51 | + <groupId>io.github.universal-variability-language</groupId> |
| 52 | + <artifactId>fm-metamodel</artifactId> |
| 53 | + <version>1.1</version> |
| 54 | +</dependency> |
64 | 55 | ``` |
65 | 56 |
|
66 | | -The `target/uvl-parser-1.0-SNAPSHOT-jar-with-dependencies.jar` includes all dependencies. |
| 57 | +Make sure that the version matches the latest release. |
67 | 58 |
|
68 | | -## Usage from Java |
69 | | -The class `de.vill.main.UVLModelFactory` exposes the static method `parse(String)` which will return an instance of a `de.vill.model.FeatureModel` class. If there is something wrong, a `de.vill.exception.ParseError` is thrown. The parser tries to parse the whole model, even if there are errors. If there are multiple errors, a `de.vill.exception.ParseErrorList` is returned which contains all errors that occurred. |
70 | | -A model can be printed with the `toString()` method of the `de.vill.model.FeatureModel` object. |
71 | | -The following snippet shows a minimal example to read and write UVL models using the jar. More usage examples that also show how to use the acquired UVLModel object can be found in [src/main/java/de/vill/main/Example.java](https://github.com/Universal-Variability-Language/uvl-parser2.0/blob/main/src/main/java/de/vill/main/Example.java) |
| 59 | +--- |
| 60 | + |
| 61 | +Now you can use the classes from this library in your own Java code! |
| 62 | + |
| 63 | +## Examples |
| 64 | + |
| 65 | +Some usage examples that show how to use the acquired UVLModel object can be found in [src/main/java/de/vill/main/Example.java](https://github.com/Universal-Variability-Language/java-fm-metamodel/blob/main/src/main/java/de/vill/main/Example.java) |
| 66 | + |
| 67 | +### Parsing |
72 | 68 |
|
73 | 69 | ```Java |
74 | | -// Read |
| 70 | +// First option: |
| 71 | +UVLModelFactory uvlModelFactory = new UVLModelFactory(); |
| 72 | +FeatureModel featureModel = uvlModelFactory.parse(Paths.get("path/to/your/file.uvl")); |
| 73 | + |
| 74 | +// Second option: |
75 | 75 | Path filePath = Paths.get(pathAsString); |
76 | 76 | String content = new String(Files.readAllBytes(filePath)); |
77 | 77 | UVLModelFactory uvlModelFactory = new UVLModelFactory(); |
78 | 78 | FeatureModel featureModel = uvlModelFactory.parse(content); |
| 79 | +``` |
| 80 | + |
| 81 | +The class `de.vill.main.UVLModelFactory` exposes the static method `parse(String)` which will return an instance of a `de.vill.model.FeatureModel` class. If there is something wrong, a `de.vill.exception.ParseError` is thrown. The parser tries to parse the whole model, even if there are errors. If there are multiple errors, a `de.vill.exception.ParseErrorList` is returned which contains all errors that occurred. |
79 | 82 |
|
| 83 | +### Modifying |
80 | 84 |
|
| 85 | +```Java |
| 86 | +Feature feature = featureModel.getFeatureMap().get(featureName); |
| 87 | +if (feature != null) { |
| 88 | + Attribute<?> attribute = feature.getAttributes().get(attributeName); |
| 89 | + if (attribute != null) { |
| 90 | + System.out.println("Name of the feature" + feature.getFeatureName()); |
| 91 | + System.out.println("Name of the attribute" + attribute.getName()); |
| 92 | + } |
| 93 | +} |
| 94 | + |
| 95 | +// Conversion |
| 96 | +ConvertTypeLevel converter = new ConvertTypeLevel(); |
| 97 | +converter.convertFeatureModel(featureModel, convertedModel); |
| 98 | +``` |
| 99 | + |
| 100 | +### Writing into a file |
| 101 | + |
| 102 | +```Java |
81 | 103 | // Write |
82 | 104 | String uvlModel = featureModel.toString(); |
83 | 105 | Path filePath = Paths.get(featureModel.getNamespace() + ".uvl"); |
84 | 106 | Files.write(filePath, uvlModel.getBytes()); |
85 | | -``` |
| 107 | +``` |
| 108 | + |
| 109 | +A model can be printed with the `toString()` method of the `de.vill.model.FeatureModel` object. |
| 110 | + |
| 111 | +## 🧪 Running Tests |
| 112 | + |
| 113 | +The Java-fm-metamodel can be tested by running: |
| 114 | + |
| 115 | +```bash |
| 116 | +mvn test |
| 117 | +``` |
| 118 | + |
| 119 | +## 📖 Citation |
| 120 | + |
| 121 | +If you use UVL in your research, please cite: |
| 122 | + |
| 123 | +```bibtex |
| 124 | +@article{UVL2024, |
| 125 | + title = {UVL: Feature modelling with the Universal Variability Language}, |
| 126 | + journal = {Journal of Systems and Software}, |
| 127 | + volume = {225}, |
| 128 | + pages = {112326}, |
| 129 | + year = {2025}, |
| 130 | + issn = {0164-1212}, |
| 131 | + doi = {https://doi.org/10.1016/j.jss.2024.112326}, |
| 132 | + url = {https://www.sciencedirect.com/science/article/pii/S0164121224003704}, |
| 133 | + author = {David Benavides and Chico Sundermann and Kevin Feichtinger and José A. Galindo and Rick Rabiser and Thomas Thüm}, |
| 134 | + keywords = {Feature model, Software product lines, Variability} |
| 135 | +} |
| 136 | +``` |
86 | 137 |
|
87 | 138 | ## Links |
| 139 | + |
88 | 140 | UVL models: |
89 | | -* https://github.com/Universal-Variability-Language/uvl-models |
| 141 | + |
| 142 | +- https://github.com/Universal-Variability-Language/uvl-models |
| 143 | + |
| 144 | +UVL parser: |
| 145 | + |
| 146 | +- https://github.com/Universal-Variability-Language/uvl-parser |
90 | 147 |
|
91 | 148 | Other parsers: |
92 | | -* https://github.com/Universal-Variability-Language/uvl-parser *deprecated, Initial UVL Parser, based on Clojure and instaparse* **UVL-Parser** |
93 | | -* https://github.com/diverso-lab/uvl-diverso/ *Under development, Antlr4 Parser* **Diverso Lab** |
94 | 149 |
|
95 | | -Usage of UVL: |
96 | | -* https://github.com/FeatureIDE/FeatureIDE *Feature modelling tool* |
| 150 | +- https://github.com/Universal-Variability-Language/uvl-parser _deprecated, Initial UVL Parser, based on Clojure and instaparse_ **UVL-Parser** |
| 151 | +- https://github.com/diverso-lab/uvl-diverso/ _Under development, Antlr4 Parser_ **Diverso Lab** |
97 | 152 |
|
| 153 | +Usage of UVL: |
98 | 154 |
|
| 155 | +- https://github.com/FeatureIDE/FeatureIDE _Feature modelling tool_ |
| 156 | +- https://github.com/SECPS/TraVarT _Transformation Tool for Variability Artifacts_ |
0 commit comments