Skip to content

Commit 6315677

Browse files
authored
Revert "Remove the usage of the global metadata/index.json from the nbt plugins" (#836)
Revert "Remove the usage of the global metadata/index.json from the nbt plugins" (#836) This reverts commit fe065ce.
1 parent fe065ce commit 6315677

38 files changed

Lines changed: 464 additions & 118 deletions

File tree

common/graalvm-reachability-metadata/src/main/java/org/graalvm/reachability/internal/index/artifacts/Artifact.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,21 +44,27 @@
4444
import java.util.regex.Pattern;
4545

4646
public class Artifact {
47+
private final String module;
4748
private final Set<String> versions;
4849
private final String directory;
4950
private final boolean latest;
5051
private final boolean override;
5152
private final Pattern defaultForPattern;
5253

53-
public Artifact(Set<String> versions, String directory,
54+
public Artifact(String module, Set<String> versions, String directory,
5455
boolean latest, boolean override, String defaultFor) {
56+
this.module = module;
5557
this.versions = versions;
5658
this.directory = directory;
5759
this.latest = latest;
5860
this.override = override;
5961
this.defaultForPattern = (defaultFor == null ? null : Pattern.compile(defaultFor));
6062
}
6163

64+
public String getModule() {
65+
return module;
66+
}
67+
6268
public Set<String> getVersions() {
6369
return versions;
6470
}

common/graalvm-reachability-metadata/src/main/java/org/graalvm/reachability/internal/index/artifacts/SingleModuleJsonVersionToConfigDirectoryIndex.java

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -51,20 +51,22 @@
5151
import java.util.ArrayList;
5252
import java.util.LinkedHashSet;
5353
import java.util.List;
54+
import java.util.Map;
5455
import java.util.Optional;
5556
import java.util.Set;
5657
import java.util.function.Predicate;
58+
import java.util.stream.Collectors;
5759

5860
public class SingleModuleJsonVersionToConfigDirectoryIndex implements VersionToConfigDirectoryIndex {
5961
private final Path moduleRoot;
60-
private final List<Artifact> artifacts;
62+
private final Map<String, List<Artifact>> index;
6163

6264
public SingleModuleJsonVersionToConfigDirectoryIndex(Path moduleRoot) {
6365
this.moduleRoot = moduleRoot;
64-
this.artifacts = parseIndexFile(moduleRoot);
66+
this.index = parseIndexFile(moduleRoot);
6567
}
6668

67-
private List<Artifact> parseIndexFile(Path rootPath) {
69+
private Map<String, List<Artifact>> parseIndexFile(Path rootPath) {
6870
Path indexFile = rootPath.resolve("index.json");
6971
try {
7072
String fileContent = Files.readString(indexFile);
@@ -73,7 +75,8 @@ private List<Artifact> parseIndexFile(Path rootPath) {
7375
for (int i = 0; i < json.length(); i++) {
7476
entries.add(fromJson(json.getJSONObject(i)));
7577
}
76-
return entries;
78+
return entries.stream()
79+
.collect(Collectors.groupingBy(Artifact::getModule));
7780
} catch (IOException e) {
7881
throw new UncheckedIOException(e);
7982
}
@@ -118,23 +121,27 @@ public Optional<DirectoryConfiguration> findLatestConfigurationFor(String groupI
118121

119122
private Optional<DirectoryConfiguration> findConfigurationFor(String groupId, String artifactId, String version,
120123
Predicate<? super Artifact> predicate) {
121-
if (artifacts.isEmpty()) {
124+
String module = groupId + ":" + artifactId;
125+
List<Artifact> artifacts = index.get(module);
126+
if (artifacts == null) {
122127
return Optional.empty();
123128
}
124129
return artifacts.stream()
130+
.filter(artifact -> artifact.getModule().equals(module))
125131
.filter(predicate)
126132
.findFirst()
127133
.map(artifact -> new DirectoryConfiguration(groupId, artifactId, version,
128134
moduleRoot.resolve(artifact.getDirectory()), artifact.isOverride()));
129135
}
130136

131137
private Artifact fromJson(JSONObject json) {
138+
String module = json.optString("module", null);
132139
Set<String> testVersions = readTestedVersions(json.optJSONArray("tested-versions"));
133140
String directory = json.optString("metadata-version", null);
134141
boolean latest = json.optBoolean("latest");
135142
boolean override = json.optBoolean("override");
136143
String defaultFor = json.optString("default-for", null);
137-
return new Artifact(testVersions, directory, latest, override, defaultFor);
144+
return new Artifact(module, testVersions, directory, latest, override, defaultFor);
138145
}
139146

140147
private Set<String> readTestedVersions(JSONArray array) {

common/graalvm-reachability-metadata/src/main/java/org/graalvm/reachability/internal/index/modules/FileSystemModuleToConfigDirectoryIndex.java

Lines changed: 16 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -40,77 +40,36 @@
4040
*/
4141
package org.graalvm.reachability.internal.index.modules;
4242

43-
import com.github.openjson.JSONArray;
44-
import com.github.openjson.JSONObject;
45-
import org.graalvm.reachability.internal.UncheckedIOException;
46-
47-
import java.io.IOException;
48-
import java.nio.file.Files;
4943
import java.nio.file.Path;
50-
import java.util.Collections;
51-
import java.util.LinkedHashSet;
5244
import java.util.Set;
5345

5446
/**
55-
* Module-to-config index which:
56-
* - Resolves the primary module directory by conventional layout (groupId/artifactId),
57-
* - Reads requires from the inner metadata/group/artifact/index.json and adds their conventional directories.
47+
* This is the default index from module to configuration directory, which first
48+
* looks into the JSON index file, and if a module isn't found there, would try
49+
* to find it in the standard FS location.
5850
*/
5951
public class FileSystemModuleToConfigDirectoryIndex implements ModuleToConfigDirectoryIndex {
60-
private final Path rootPath;
52+
private final JsonModuleToConfigDirectoryIndex jsonIndex;
53+
private final StandardLocationModuleToConfigDirectoryIndex fsIndex;
6154

6255
public FileSystemModuleToConfigDirectoryIndex(Path rootPath) {
63-
this.rootPath = rootPath;
56+
this.jsonIndex = new JsonModuleToConfigDirectoryIndex(rootPath);
57+
this.fsIndex = new StandardLocationModuleToConfigDirectoryIndex(rootPath);
6458
}
6559

6660
/**
67-
* Returns the directories containing the candidate configurations for the given module.
68-
* <p>
69-
* - Always includes the conventional module directory if present: rootPath/groupId/artifactId
70-
* - Additionally includes conventional directories of any modules listed in "requires" of the inner index.json
71-
* - Only a single-level requires expansion is performed
61+
* Returns the directory containing the candidate configurations for the given module.
62+
*
63+
* @param groupId the group of the module
64+
* @param artifactId the artifact of the module
65+
* @return the configuration directory
7266
*/
7367
@Override
7468
public Set<Path> findConfigurationDirectories(String groupId, String artifactId) {
75-
Path base = rootPath.resolve(groupId + "/" + artifactId);
76-
if (!Files.isDirectory(base)) {
77-
return Collections.emptySet();
78-
}
79-
80-
Path indexFile = base.resolve("index.json");
81-
if (Files.isRegularFile(indexFile)) {
82-
Set<Path> result = new LinkedHashSet<>();
83-
// Always include the base directory so its index.json is parsed,
84-
// even if it doesn't contain configuration files itself.
85-
result.add(base);
86-
try {
87-
String content = Files.readString(indexFile);
88-
JSONArray entries = new JSONArray(content);
89-
for (int i = 0; i < entries.length(); i++) {
90-
JSONObject entry = entries.getJSONObject(i);
91-
JSONArray requires = entry.optJSONArray("requires");
92-
if (requires == null) {
93-
continue;
94-
}
95-
for (int j = 0; j < requires.length(); j++) {
96-
String req = requires.getString(j);
97-
int sep = req.indexOf(':');
98-
if (sep > 0) {
99-
String reqGroup = req.substring(0, sep);
100-
String reqArtifact = req.substring(sep + 1);
101-
Path reqDir = rootPath.resolve(reqGroup + "/" + reqArtifact);
102-
if (Files.isDirectory(reqDir)) {
103-
result.add(reqDir);
104-
}
105-
}
106-
}
107-
}
108-
} catch (IOException e) {
109-
throw new UncheckedIOException(e);
110-
}
111-
return result;
69+
Set<Path> fromIndex = jsonIndex.findConfigurationDirectories(groupId, artifactId);
70+
if (!fromIndex.isEmpty()) {
71+
return fromIndex;
11272
}
113-
114-
return Collections.singleton(base);
73+
return fsIndex.findConfigurationDirectories(groupId, artifactId);
11574
}
11675
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
/*
2+
* Copyright (c) 2020, 2022 Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* The Universal Permissive License (UPL), Version 1.0
6+
*
7+
* Subject to the condition set forth below, permission is hereby granted to any
8+
* person obtaining a copy of this software, associated documentation and/or
9+
* data (collectively the "Software"), free of charge and under any and all
10+
* copyright rights in the Software, and any and all patent rights owned or
11+
* freely licensable by each licensor hereunder covering either (i) the
12+
* unmodified Software as contributed to or provided by such licensor, or (ii)
13+
* the Larger Works (as defined below), to deal in both
14+
*
15+
* (a) the Software, and
16+
*
17+
* (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
18+
* one is included with the Software each a "Larger Work" to which the Software
19+
* is contributed by such licensors),
20+
*
21+
* without restriction, including without limitation the rights to copy, create
22+
* derivative works of, display, perform, and distribute the Software and make,
23+
* use, sell, offer for sale, import, export, have made, and have sold the
24+
* Software and the Larger Work(s), and to sublicense the foregoing rights on
25+
* either these or other terms.
26+
*
27+
* This license is subject to the following condition:
28+
*
29+
* The above copyright notice and either this complete permission notice or at a
30+
* minimum a reference to the UPL must be included in all copies or substantial
31+
* portions of the Software.
32+
*
33+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
34+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
35+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
36+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
37+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
38+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
39+
* SOFTWARE.
40+
*/
41+
package org.graalvm.reachability.internal.index.modules;
42+
43+
import com.github.openjson.JSONArray;
44+
import com.github.openjson.JSONObject;
45+
import org.graalvm.reachability.internal.UncheckedIOException;
46+
47+
import java.io.IOException;
48+
import java.nio.file.Files;
49+
import java.nio.file.Path;
50+
import java.util.ArrayList;
51+
import java.util.Collections;
52+
import java.util.HashMap;
53+
import java.util.List;
54+
import java.util.Map;
55+
import java.util.Objects;
56+
import java.util.Set;
57+
import java.util.stream.Collectors;
58+
import java.util.stream.Stream;
59+
60+
public class JsonModuleToConfigDirectoryIndex implements ModuleToConfigDirectoryIndex {
61+
private final Path rootPath;
62+
private final Map<String, Set<Path>> index;
63+
64+
public JsonModuleToConfigDirectoryIndex(Path rootPath) {
65+
this.rootPath = rootPath;
66+
this.index = parseIndexFile(rootPath);
67+
}
68+
69+
private Map<String, Set<Path>> parseIndexFile(Path rootPath) {
70+
Path indexFile = rootPath.resolve("index.json");
71+
try {
72+
String fileContent = Files.readString(indexFile);
73+
JSONArray json = new JSONArray(fileContent);
74+
List<ModuleEntry> entries = new ArrayList<>();
75+
for (int i = 0; i < json.length(); i++) {
76+
entries.add(fromJson(json.getJSONObject(i)));
77+
}
78+
Map<String, List<ModuleEntry>> moduleToEntries = entries.stream()
79+
.collect(Collectors.groupingBy(ModuleEntry::getModule));
80+
Map<String, Set<Path>> index = new HashMap<>(moduleToEntries.size());
81+
for (Map.Entry<String, List<ModuleEntry>> entry : moduleToEntries.entrySet()) {
82+
String key = entry.getKey();
83+
Set<Path> dirs = entry.getValue()
84+
.stream()
85+
.flatMap(module -> Stream.concat(
86+
Stream.of(module.getModuleDirectory()),
87+
module.getRequires().stream().flatMap(e -> {
88+
List<ModuleEntry> moduleEntries = moduleToEntries.get(e);
89+
if (moduleEntries == null) {
90+
throw new IllegalStateException("Module " + module.getModule() + " requires module " + e + " which is not found in index");
91+
}
92+
return moduleEntries.stream().map(ModuleEntry::getModuleDirectory);
93+
})
94+
))
95+
.filter(Objects::nonNull)
96+
.map(rootPath::resolve)
97+
.collect(Collectors.toSet());
98+
index.put(key, dirs);
99+
}
100+
return index;
101+
} catch (IOException e) {
102+
throw new UncheckedIOException(e);
103+
}
104+
105+
}
106+
107+
private ModuleEntry fromJson(JSONObject json) {
108+
String module = json.optString("module", null);
109+
String moduleDirectory = json.optString("directory", null);
110+
List<String> requires = readRequires(json.optJSONArray("requires"));
111+
return new ModuleEntry(module, moduleDirectory, requires);
112+
}
113+
114+
private List<String> readRequires(JSONArray array) {
115+
List<String> requires = new ArrayList<>();
116+
if (array != null) {
117+
for (int i = 0; i < array.length(); i++) {
118+
requires.add(array.getString(i));
119+
}
120+
}
121+
return requires;
122+
}
123+
124+
/**
125+
* Returns the directory containing the candidate configurations for the given module.
126+
*
127+
* @param groupId the group of the module
128+
* @param artifactId the artifact of the module
129+
* @return the configuration directory
130+
*/
131+
@Override
132+
public Set<Path> findConfigurationDirectories(String groupId, String artifactId) {
133+
String key = groupId + ":" + artifactId;
134+
if (!index.containsKey(key)) {
135+
return Collections.emptySet();
136+
}
137+
return index.get(key);
138+
}
139+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/*
2+
* Copyright (c) 2020, 2022 Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* The Universal Permissive License (UPL), Version 1.0
6+
*
7+
* Subject to the condition set forth below, permission is hereby granted to any
8+
* person obtaining a copy of this software, associated documentation and/or
9+
* data (collectively the "Software"), free of charge and under any and all
10+
* copyright rights in the Software, and any and all patent rights owned or
11+
* freely licensable by each licensor hereunder covering either (i) the
12+
* unmodified Software as contributed to or provided by such licensor, or (ii)
13+
* the Larger Works (as defined below), to deal in both
14+
*
15+
* (a) the Software, and
16+
*
17+
* (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
18+
* one is included with the Software each a "Larger Work" to which the Software
19+
* is contributed by such licensors),
20+
*
21+
* without restriction, including without limitation the rights to copy, create
22+
* derivative works of, display, perform, and distribute the Software and make,
23+
* use, sell, offer for sale, import, export, have made, and have sold the
24+
* Software and the Larger Work(s), and to sublicense the foregoing rights on
25+
* either these or other terms.
26+
*
27+
* This license is subject to the following condition:
28+
*
29+
* The above copyright notice and either this complete permission notice or at a
30+
* minimum a reference to the UPL must be included in all copies or substantial
31+
* portions of the Software.
32+
*
33+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
34+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
35+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
36+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
37+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
38+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
39+
* SOFTWARE.
40+
*/
41+
package org.graalvm.reachability.internal.index.modules;
42+
43+
import java.nio.file.Files;
44+
import java.nio.file.Path;
45+
import java.util.Collections;
46+
import java.util.Set;
47+
48+
public class StandardLocationModuleToConfigDirectoryIndex implements ModuleToConfigDirectoryIndex {
49+
private final Path rootPath;
50+
51+
public StandardLocationModuleToConfigDirectoryIndex(Path rootPath) {
52+
this.rootPath = rootPath;
53+
}
54+
55+
@Override
56+
public Set<Path> findConfigurationDirectories(String groupId, String artifactId) {
57+
Path candidate = rootPath.resolve(groupId + "/" + artifactId);
58+
if (Files.isDirectory(candidate)) {
59+
return Collections.singleton(candidate);
60+
}
61+
return Collections.emptySet();
62+
}
63+
}

0 commit comments

Comments
 (0)