Skip to content

Commit a7dc5e4

Browse files
authored
Merge pull request #2 from MiriamGaus/update_versions
Update versions
2 parents 6166029 + 64ea69e commit a7dc5e4

8 files changed

Lines changed: 83 additions & 73 deletions

File tree

.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,3 +160,9 @@ buildNumber.properties
160160
.classpath
161161

162162
# End of https://www.toptal.com/developers/gitignore/api/maven,intellij,java
163+
164+
# local changes
165+
/src/main/java/uvl
166+
/.vscode
167+
/src/main/java/de/vill/main/modified_files/*
168+
!/src/main/java/de/vill/main/modified_files/.gitkeep

pom.xml

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@
4949
<developerConnection>scm:git:git@github.com:Universal-Variability-Language/java-fm-metamodel.git</developerConnection>
5050
<url>https://github.com/Universal-Variability-Language/java-fm-metamodel</url>
5151
<tag>HEAD</tag>
52-
</scm>
52+
</scm>
5353

5454
<distributionManagement>
5555
<snapshotRepository>
@@ -63,9 +63,9 @@
6363
</distributionManagement>
6464

6565
<properties>
66-
<antlr4.version>4.13.1</antlr4.version>
67-
<maven.compiler.source>11</maven.compiler.source>
68-
<maven.compiler.target>11</maven.compiler.target>
66+
<antlr4.version>4.13.2</antlr4.version>
67+
<maven.compiler.source>21</maven.compiler.source>
68+
<maven.compiler.target>21</maven.compiler.target>
6969
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
7070
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
7171
</properties>
@@ -74,23 +74,23 @@
7474
<dependency>
7575
<groupId>org.antlr</groupId>
7676
<artifactId>antlr4-runtime</artifactId>
77-
<version>4.13.1</version>
77+
<version>${antlr4.version}</version>
7878
</dependency>
79-
<dependency>
79+
<dependency><!-- TODO: Test when new version online, isn't working at the moment-->
8080
<groupId>io.github.universal-variability-language</groupId>
8181
<artifactId>uvl-parser</artifactId>
8282
<version>0.3</version>
8383
</dependency>
8484
<dependency>
8585
<groupId>org.junit.jupiter</groupId>
8686
<artifactId>junit-jupiter</artifactId>
87-
<version>5.8.2</version>
87+
<version>5.13.1</version>
8888
<scope>test</scope>
8989
</dependency>
9090
<dependency>
9191
<groupId>com.google.guava</groupId>
9292
<artifactId>guava</artifactId>
93-
<version>31.0.1-jre</version>
93+
<version>33.4.8-jre</version>
9494
</dependency>
9595
</dependencies>
9696

@@ -99,7 +99,7 @@
9999
<plugin>
100100
<groupId>org.apache.maven.plugins</groupId>
101101
<artifactId>maven-surefire-plugin</artifactId>
102-
<version>2.22.0</version>
102+
<version>3.5.3</version>
103103
</plugin>
104104
<plugin>
105105
<artifactId>maven-assembly-plugin</artifactId>
@@ -117,7 +117,7 @@
117117
<plugin>
118118
<groupId>org.apache.maven.plugins</groupId>
119119
<artifactId>maven-compiler-plugin</artifactId>
120-
<version>3.8.1</version>
120+
<version>3.14.0</version>
121121
<configuration>
122122
<source>${maven.compiler.source}</source>
123123
<target>${maven.compiler.target}</target>
@@ -127,7 +127,7 @@
127127
<plugin>
128128
<groupId>org.apache.maven.plugins</groupId>
129129
<artifactId>maven-gpg-plugin</artifactId>
130-
<version>1.5</version>
130+
<version>3.2.7</version>
131131
<executions>
132132
<execution>
133133
<id>sign-artifacts</id>
@@ -142,7 +142,7 @@
142142
<plugin>
143143
<groupId>org.sonatype.plugins</groupId>
144144
<artifactId>nexus-staging-maven-plugin</artifactId>
145-
<version>1.6.7</version>
145+
<version>1.7.0</version>
146146
<extensions>true</extensions>
147147
<configuration>
148148
<serverId>ossrh</serverId>
@@ -154,7 +154,7 @@
154154
<plugin>
155155
<groupId>org.apache.maven.plugins</groupId>
156156
<artifactId>maven-source-plugin</artifactId>
157-
<version>3.2.1</version>
157+
<version>3.3.1</version>
158158
<executions>
159159
<execution>
160160
<id>attach-sources</id>
@@ -167,7 +167,7 @@
167167
<plugin>
168168
<groupId>org.apache.maven.plugins</groupId>
169169
<artifactId>maven-javadoc-plugin</artifactId>
170-
<version>3.2.0</version>
170+
<version>3.11.2</version>
171171
<executions>
172172
<execution>
173173
<id>attach-javadocs</id>

src/main/java/de/vill/main/Example.java

Lines changed: 56 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package de.vill.main;
22

3-
import de.vill.config.Configuration;
43
import de.vill.model.Attribute;
54
import de.vill.model.Feature;
65
import de.vill.model.FeatureModel;
@@ -16,25 +15,31 @@
1615

1716
public class Example {
1817
public static void main(String[] args) throws IOException {
19-
FeatureModel featureModel = loadUVLFeatureModelFromFile("test.uvl");
18+
// Load a UVL feature model from a file
19+
FeatureModel featureModel = loadUVLFeatureModelFromFile("src/test/resources/test_resources/parsing/complex/bike.uvl");
20+
System.out.println("Loaded feature model from file:" + featureModel.toString());
2021

21-
//traverse all features depth first search
22+
// Traverse all features in the model using depth-first search
23+
System.out.println("Traversing all features:");
2224
traverseAllFeatures(featureModel.getRootFeature());
2325

24-
//get constraints of feature model from constraints section (no constraints from submodels or attribtues)
25-
List<Constraint> ownConstraint = featureModel.getOwnConstraints();
26+
// Retrieve constraints defined directly in the feature model (excluding submodels and attributes)
27+
List<Constraint> ownConstraints = featureModel.getOwnConstraints();
28+
System.out.println("Number of own constraints: " + ownConstraints.size());
2629

27-
//traverse a constraint depth first search
28-
if (ownConstraint.size() > 0) {
29-
traverseConstraint(ownConstraint.get(0));
30+
// If there are constraints, traverse the first one
31+
if (!ownConstraints.isEmpty()) {
32+
System.out.println("Traversing first own constraint:");
33+
traverseConstraint(ownConstraints.get(0));
3034
}
3135

32-
//get all constraints of feature model and submodels and attributes
33-
List<Constraint> allConstraint = featureModel.getConstraints();
36+
// Retrieve all constraints, including those from submodels and attributes
37+
List<Constraint> allConstraints = featureModel.getConstraints();
38+
System.out.println("Total constraints (including submodels/attributes): " + allConstraints.size());
3439

35-
//get attribute from feature
36-
String featureName = "featureName";
37-
String attributeName = "attributeName";
40+
// Access a specific attribute of a feature
41+
String featureName = "Brake";
42+
String attributeName = "Weight";
3843
Feature feature = featureModel.getFeatureMap().get(featureName);
3944
if (feature != null) {
4045
Attribute<?> attribute = feature.getAttributes().get(attributeName);
@@ -48,83 +53,80 @@ public static void main(String[] args) throws IOException {
4853
System.err.println("Feature " + featureName + " not found!");
4954
}
5055

51-
//make feature abstract
52-
featureName = "featureName";
56+
// Make a feature abstract by adding an "abstract" attribute
57+
featureName = "Inch";
5358
feature = featureModel.getFeatureMap().get(featureName);
5459
if (feature != null) {
5560
feature.getAttributes().put("abstract", new Attribute<>("abstract", true, feature));
61+
System.out.println("Feature " + featureName + " set to abstract.");
5662
} else {
5763
System.err.println("Feature " + featureName + " not found!");
5864
}
5965

60-
//change newline and tabulator symbol for printing
61-
Configuration.setTabulatorSymbol(" ");
62-
Configuration.setNewlineSymbol("\n");
63-
64-
//safe a single uvl model (this ignores any submodels)
66+
// Save the feature model as a single UVL file (ignoring submodels)
6567
String uvlModel = featureModel.toString();
66-
Path filePath = Paths.get("test_singleModel.uvl");
67-
Files.write(filePath, uvlModel.getBytes());
68+
Path filePath = Paths.get("src/main/java/de/vill/main/modified_files/test_singleModel.uvl");
69+
try {
70+
Files.write(filePath, uvlModel.getBytes());
71+
} catch (IOException e) {
72+
System.err.println("Error saving single UVL model: " + e.getMessage());
73+
return;
74+
}
75+
System.out.println("Saved single UVL model to test_singleModel.uvl");
6876

69-
//safe a decomposed uvl model with all its submodels to individual files
77+
// Save a decomposed UVL model with all submodels to individual files
7078
Map<String, String> modelList = featureModel.decomposedModelToString();
7179
for (Map.Entry<String, String> uvlSubModel : modelList.entrySet()) {
72-
//safe submodel in sub directory directory with namespace as name
73-
Files.createDirectories(Paths.get("./subModels/"));
74-
filePath = Paths.get("./subModels/" + uvlSubModel.getKey() + ".uvl");
80+
Files.createDirectories(Paths.get("./src/main/java/de/vill/main/modified_files/subModels/"));
81+
filePath = Paths.get("./src/main/java/de/vill/main/modified_files/subModels/" + uvlSubModel.getKey() + ".uvl");
7582
Files.write(filePath, uvlSubModel.getValue().getBytes());
83+
System.out.println("Saved submodel: " + uvlSubModel.getKey());
7684
}
7785

78-
//create a single uvl representation from a decomposed model and safe it to a single file
86+
// Compose a single UVL representation from a decomposed model and save it
7987
uvlModel = featureModel.composedModelToString();
80-
filePath = Paths.get("test_composedModel.uvl");
88+
filePath = Paths.get("src/main/java/de/vill/main/modified_files/test_composedModel.uvl");
8189
Files.write(filePath, uvlModel.getBytes());
90+
System.out.println("Saved composed UVL model to test_composedModel.uvl");
8291
}
8392

93+
// TODO: Add conversion example methods for converting between different formats (e.g., JSON, XML, etc.)
94+
95+
// ----------------------------------- Utility Methods -----------------------------------
96+
8497
/**
85-
* Parse uvl model from file (if decomposed all submodels must be in the current working directory)
86-
*
87-
* @param path path to the file with uvl model
88-
* @return the uvl model described in the file
89-
* @throws IOException for io exceptions while loading the file content
98+
* Loads a UVL feature model from a single file.
99+
* If the model is decomposed, all submodels must be present in the current working directory.
100+
* @param path The path to the UVL model file.
101+
* @return The loaded feature model.
102+
* @throws IOException If an I/O error occurs while reading the file.
90103
*/
91104
private static FeatureModel loadUVLFeatureModelFromFile(String path) throws IOException {
92-
Path filePath = Paths.get(path);
93-
String content = new String(Files.readAllBytes(filePath));
94105
UVLModelFactory uvlModelFactory = new UVLModelFactory();
95-
FeatureModel featureModel = uvlModelFactory.parse(content);
106+
FeatureModel featureModel = uvlModelFactory.parse(Paths.get(path));
96107
return featureModel;
97108
}
98109

99110
/**
100-
* Parse a decomposed uvl model where all submodels are in a directory and named according to their namespaces.
101-
*
102-
* @param rootModelPath Path to the uvl root model file
103-
* @param subModelDir Path to the directory with all submodels
104-
* @return the uvl model described in the file
105-
* @throws IOException for io exceptions while loading the file content
111+
* Traverses a constraint and all its sub-parts using depth-first search.
112+
* @param constraint The constraint to traverse.
106113
*/
107-
private static FeatureModel loadUVLFeatureModelFromDirectory(String rootModelPath, String subModelDir) throws IOException {
108-
Path filePath = Paths.get(rootModelPath);
109-
String content = new String(Files.readAllBytes(filePath));
110-
UVLModelFactory uvlModelFactory = new UVLModelFactory();
111-
FeatureModel featureModel = uvlModelFactory.parse(content, subModelDir);
112-
return featureModel;
113-
}
114-
115-
116114
private static void traverseConstraint(Constraint constraint) {
115+
System.out.println("\tVisiting constraint: " + constraint);
117116
for (Constraint subConstraint : constraint.getConstraintSubParts()) {
118-
//... do something with constraint
119117
traverseConstraint(subConstraint);
120118
}
121119
}
122120

121+
/**
122+
* Traverses all features in the feature tree using depth-first search.
123+
* @param feature The root feature to start traversal from.
124+
*/
123125
public static void traverseAllFeatures(Feature feature) {
126+
System.out.println("\tVisiting feature: " + feature.getFeatureName());
124127
for (Group group : feature.getChildren()) {
125128
for (Feature childFeature : group.getFeatures()) {
126-
//... do something with feature
127-
//or stop at submodel with if(!childfeature.isSubmodelroot())
129+
// Optionally, skip submodel roots: if (!childFeature.isSubmodelroot()) { ... }
128130
traverseAllFeatures(childFeature);
129131
}
130132
}

src/main/java/de/vill/main/UVLListener.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,11 @@ public void enterFeature(UVLJavaParser.FeatureContext ctx) {
215215
if (feature == null) {
216216
errorList.add(new ParseError("Feature " + featureReference + " is imported, but there is import with that name."));
217217
return;
218+
} else if (importedFeatures.containsKey(featureReference)) {
219+
errorList.add(new ParseError("Duplicate feature name: " + featureReference + " (line: " + ctx.getStart().getLine() + ")"));
220+
return;
218221
}
222+
importedFeatures.put(featureReference, feature);
219223
featureStack.push(feature);
220224
Group parentGroup = groupStack.peek();
221225
fmBuilder.addFeature(feature, parentGroup);
@@ -475,7 +479,6 @@ public void exitStringLiteralExpression(UVLJavaParser.StringLiteralExpressionCon
475479
Expression expression = new StringExpression(ctx.STRING().getText().replace("'", ""));
476480
expressionStack.push(expression);
477481
if (expressionStack.peek() instanceof LiteralExpression) {
478-
LiteralExpression literalExpression = (LiteralExpression) expressionStack.peek();
479482
fmBuilder.addLanguageLevel(LanguageLevel.TYPE_LEVEL);
480483
fmBuilder.addLanguageLevel(LanguageLevel.STRING_CONSTRAINTS);
481484
}

src/main/java/de/vill/main/UVLModelFactory.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@
3838
import java.nio.file.Path;
3939
import java.nio.file.Paths;
4040
import java.util.*;
41-
import java.util.function.Function;
4241

4342
public class UVLModelFactory {
4443

@@ -128,7 +127,6 @@ public void syntaxError(Recognizer<?, ?> recognizer, Object offendingSymbol, int
128127
UVLListener uvlListener = new UVLListener();
129128
ParseTreeWalker walker = new ParseTreeWalker();
130129
walker.walk(uvlListener, UVLJavaParser.constraintLine());
131-
Constraint constraint = null;
132130

133131
return uvlListener.getConstraint();
134132
}

src/main/java/de/vill/main/modified_files/.gitkeep

Whitespace-only changes.

src/test/java/de/vill/model/ExpressionTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ class ExpressionTest {
1818
void testMathExpressionsModel() {
1919
// get the feature model and parse it using the UVLModelFactory
2020
UVLModelFactory uvlModelFactory = new UVLModelFactory();
21-
FeatureModel featureModel = uvlModelFactory.parse(Paths.get("src/test/resources/parsing/expressions.uvl"));
21+
FeatureModel featureModel = uvlModelFactory.parse(Paths.get("src/test/resources/test_resources/parsing/arithmetic_level/expressions.uvl"));
2222
// select features for evaluation
2323
Map<String, Feature> featureMap = featureModel.getFeatureMap();
2424
Set<Feature> selectedFeatures = Set.of(
@@ -43,7 +43,7 @@ void testMathExpressionsModel() {
4343
void testAggregateFunctions() {
4444
// get the feature model and parse it using the UVLModelFactory
4545
UVLModelFactory uvlModelFactory = new UVLModelFactory();
46-
FeatureModel featureModel = uvlModelFactory.parse(Paths.get("src/test/resources/parsing/aggregateFunctions.uvl"));
46+
FeatureModel featureModel = uvlModelFactory.parse(Paths.get("src/test/resources/test_resources/parsing/arithmetic_level/aggregate_functions/aggregateFunctions.uvl"));
4747
// select features for evaluation
4848
Map<String, Feature> featureMap = featureModel.getFeatureMap();
4949
Set<Feature> selectedFeatures = Set.of(

src/test/resources

Submodule resources added at 8e40f09

0 commit comments

Comments
 (0)