forked from projekt-opal/licenses
-
Notifications
You must be signed in to change notification settings - Fork 3
/
BackMapping.java
175 lines (152 loc) · 5.46 KB
/
BackMapping.java
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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
package org.dice_research.opal.licenses;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class BackMapping {
/**
* Gets compatible licenses.
*
* Creates set of call of
* {@link #getCompatibleLicensesList(List, Attributes, KnowledgeBase)}.
*/
public Set<License> getCompatibleLicenses(List<License> inputLicenses, Attributes setting,
KnowledgeBase knowledgeBase) {
return new HashSet<License>(getCompatibleLicensesList(inputLicenses, setting, knowledgeBase));
}
/**
* Gets compatible licenses.
*
* @param inputLicenses Combination of licenses for which other compatible
* licenses are requested
* @param setting Attributes, based on internal values, typically computed
* by operator
* @param knowledgeBase Knowledgebase with all known licenses
*
* @return List of compatible licenses
*/
public List<License> getCompatibleLicensesList(List<License> inputLicenses, Attributes setting,
KnowledgeBase knowledgeBase) {
// No license to check -> no result
if (inputLicenses.isEmpty()) {
return new ArrayList<>(0);
}
// If a derivates-allowed permission is not set for an input license -> no
// result
for (Attribute attribute : knowledgeBase.getSortedAttributes().getList()) {
if (attribute.isTypePermissionOfDerivates()) {
// If there is one license not allowing derivates -> no result
for (License license : inputLicenses) {
if (!license.getAttributes().getAttribute(attribute.getUri()).getValue()) {
return new ArrayList<>(0);
}
}
}
}
// Filter by attributes
List<License> resultingLicenses = removeLessRestrictive(setting, knowledgeBase.getLicenses(), false);
// Remove incompatible share-alike restrictions
for (License shareAlikeInputLicense : inputLicenses) {
for (License license : knowledgeBase.getLicenses()) {
if (shareAlikeInputLicense.isAttribueEquality()) {
List<License> licenseList = new LinkedList<>();
licenseList.add(license);
if (removeNotCompatibleShareAlike(shareAlikeInputLicense, licenseList, false).isEmpty()) {
resultingLicenses.remove(license);
}
}
}
}
return resultingLicenses;
}
/**
* Gets matching licenses based on internal values.
*/
protected List<License> removeLessRestrictive(Attributes setting, List<License> licenses,
boolean includeMetaAttributes) {
List<License> results = new LinkedList<>();
List<Attribute> settingAttributes = setting.getList();
boolean[] settingValues = setting.getValuesArray();
licenseLoop: for (License license : licenses) {
boolean[] licenseValues = license.getAttributes().getValuesArray();
valueLoop: for (int i = 0; i < settingValues.length; i++) {
if (!includeMetaAttributes && settingAttributes.get(i).isMetaAttribute()) {
continue valueLoop;
}
if (settingAttributes.get(i).getType().equals(Permission.TYPE)) {
// Not compatible: Setting restricted and license open
if (!settingValues[i] && licenseValues[i]) {
continue licenseLoop;
}
}
else if (settingAttributes.get(i).getType().equals(Prohibition.TYPE)) {
// Not compatible: Setting restricted and license open
if (settingValues[i] && !licenseValues[i]) {
continue licenseLoop;
}
}
else if (settingAttributes.get(i).getType().equals(Requirement.TYPE)) {
// Not compatible: Setting restricted and license open
if (settingValues[i] && !licenseValues[i]) {
continue licenseLoop;
}
}
else {
throw new RuntimeException("Unknown type");
}
}
results.add(license);
}
return results;
}
/**
* Gets matching licenses based on internal values.
*
* Used for share-alike comparison.
*/
protected List<License> removeNotCompatibleShareAlike(License shareAlikeLicense, List<License> licenses,
boolean includeMetaAttributes) {
List<License> results = new LinkedList<>();
List<Attribute> settingAttributes = shareAlikeLicense.getAttributes().getList();
boolean[] settingValues = shareAlikeLicense.getAttributes().getValuesArray();
short ccVersion = extractCreativeCommonsVersion(shareAlikeLicense.getUri());
licenseLoop: for (License license : licenses) {
boolean[] licenseValues = license.getAttributes().getValuesArray();
valueLoop: for (int i = 0; i < settingValues.length; i++) {
// Ignore meta attributes except of share-alike
if (!includeMetaAttributes && settingAttributes.get(i).isMetaAttribute()
&& !settingAttributes.get(i).isTypeAttribueEquality()) {
continue valueLoop;
}
// Not compatible: Difference in permission / prohibition / requirement
if (settingValues[i] != licenseValues[i]) {
continue licenseLoop;
}
}
// CC SA*: Also exclude, if input-license version is lower
if (ccVersion != -1) {
short licenseCcVersion = extractCreativeCommonsVersion(license.getUri());
if (licenseCcVersion != -1 && ccVersion < licenseCcVersion) {
continue licenseLoop;
}
}
results.add(license);
}
return results;
}
/**
* Searches for 'creativecommons' string and extracts major version.
*/
private short extractCreativeCommonsVersion(String uri) {
Pattern pattern = Pattern.compile(".*creativecommons.*(\\d)\\.\\d.*");
Matcher matcher = pattern.matcher(uri);
if (matcher.matches()) {
return Short.parseShort(matcher.group(1));
} else {
return -1;
}
}
}