-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathConvertGroupCardinality.java
More file actions
90 lines (76 loc) · 3.35 KB
/
ConvertGroupCardinality.java
File metadata and controls
90 lines (76 loc) · 3.35 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
package de.vill.conversion;
import com.google.common.collect.Sets;
import de.vill.model.Feature;
import de.vill.model.FeatureModel;
import de.vill.model.Group;
import de.vill.model.LanguageLevel;
import de.vill.model.constraint.*;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
public class ConvertGroupCardinality implements IConversionStrategy {
@Override
public Set<LanguageLevel> getLevelsToBeRemoved() {
return new HashSet<>(Arrays.asList(LanguageLevel.GROUP_CARDINALITY));
}
@Override
public Set<LanguageLevel> getTargetLevelsOfConversion() {
return new HashSet<>(Arrays.asList(LanguageLevel.BOOLEAN_LEVEL));
}
@Override
public void convertFeatureModel(FeatureModel rootFeatureModel, FeatureModel featureModel) {
searchGroupCardinalities(featureModel.getRootFeature(), featureModel);
}
private void searchGroupCardinalities(Feature feature, FeatureModel featureModel) {
for (Group group : feature.getChildren()) {
if (group.GROUPTYPE.equals(Group.GroupType.GROUP_CARDINALITY)) {
removeGroupCardinality(group, featureModel);
}
for (Feature subFeature : group.getFeatures()) {
if (!subFeature.isSubmodelRoot()) {
searchGroupCardinalities(subFeature, featureModel);
}
}
}
}
private void removeGroupCardinality(Group group, FeatureModel featureModel) {
group.GROUPTYPE = Group.GroupType.OPTIONAL;
Set<Feature> groupMembers = new HashSet<>(group.getFeatures());
int lowerBound = group.getCardinality().lower;
int upperBound = Math.min(group.getCardinality().upper, groupMembers.size());
Set<Set<Feature>> featureCombinations = new HashSet<>();
for (int i = lowerBound; i <= upperBound; i++) {
featureCombinations.addAll(Sets.combinations(groupMembers, i));
}
Set<Constraint> disjunction = new HashSet<>();
for (Set<Feature> configuration : featureCombinations) {
disjunction.add(createConjunction(configuration, new HashSet<>(groupMembers)));
}
featureModel.getOwnConstraints().add(new ImplicationConstraint(new LiteralConstraint(group.getParentFeature()), new ParenthesisConstraint(createDisjunction(disjunction))));
}
private Constraint createConjunction(Set<Feature> selectedFeatures, Set<Feature> allFeatures) {
Constraint constraint;
Feature feature = null;
if (!allFeatures.isEmpty()) {
feature = allFeatures.iterator().next();
allFeatures.remove(feature);
}
Constraint literalConstraint = new LiteralConstraint(feature);
if (!selectedFeatures.contains(feature)) {
literalConstraint = new NotConstraint(literalConstraint);
}
if (allFeatures.size() == 0) {
constraint = literalConstraint;
} else {
constraint = new AndConstraint(literalConstraint, createConjunction(selectedFeatures, allFeatures));
}
return constraint;
}
private Constraint createDisjunction(Set<Constraint> constraints) {
MultiOrConstraint orConstraint = new MultiOrConstraint();
for (Constraint constraint : constraints) {
orConstraint.add_sub_part(constraint);
}
return orConstraint;
}
}