Skip to content

Commit fbb253f

Browse files
committed
Generate javadoc jars
1 parent 84b2dd5 commit fbb253f

File tree

5 files changed

+250
-1
lines changed

5 files changed

+250
-1
lines changed

java/client/src/org/openqa/selenium/BUILD.bazel

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
load("//java:version.bzl", "SE_VERSION")
2-
load("//java:defs.bzl", "java_dist_zip", "java_export")
2+
load("//java:defs.bzl", "java_dist_zip", "java_export", "javadoc")
33

44
filegroup(
55
name = "template-pom",
@@ -51,6 +51,13 @@ java_export(
5151
],
5252
)
5353

54+
javadoc(
55+
name = "core-docs",
56+
deps = [
57+
":core",
58+
],
59+
)
60+
5461
java_dist_zip(
5562
name = "client-zip",
5663
files = [
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
java_binary(
2+
name = "javadoc",
3+
main_class = "org.openqa.selenium.tools.javadoc.JavadocJarMaker",
4+
srcs = glob(["*.java"]),
5+
deps = [],
6+
visibility = [
7+
"//visibility:public",
8+
]
9+
)
Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
package org.openqa.selenium.tools.javadoc;
2+
3+
import javax.tools.DocumentationTool;
4+
import javax.tools.JavaFileObject;
5+
import javax.tools.StandardJavaFileManager;
6+
import javax.tools.ToolProvider;
7+
import java.io.File;
8+
import java.io.IOException;
9+
import java.io.InputStream;
10+
import java.io.OutputStream;
11+
import java.io.StringWriter;
12+
import java.io.UncheckedIOException;
13+
import java.io.Writer;
14+
import java.nio.charset.StandardCharsets;
15+
import java.nio.file.Files;
16+
import java.nio.file.Path;
17+
import java.nio.file.Paths;
18+
import java.util.ArrayList;
19+
import java.util.Comparator;
20+
import java.util.HashSet;
21+
import java.util.List;
22+
import java.util.Locale;
23+
import java.util.Set;
24+
import java.util.stream.Collectors;
25+
import java.util.zip.ZipEntry;
26+
import java.util.zip.ZipInputStream;
27+
import java.util.zip.ZipOutputStream;
28+
29+
public class JavadocJarMaker {
30+
31+
public static void main(String[] args) throws IOException {
32+
Set<Path> sourceJars = new HashSet<>();
33+
Path out = null;
34+
Set<Path> classpath = new HashSet<>();
35+
36+
for (int i = 0; i < args.length; i++) {
37+
String flag = args[i];
38+
String next = args[++i];
39+
40+
switch (flag) {
41+
case "--cp":
42+
classpath.add(Paths.get(next));
43+
break;
44+
45+
case "--in":
46+
sourceJars.add(Paths.get(next));
47+
break;
48+
49+
case "--out":
50+
out = Paths.get(next);
51+
break;
52+
}
53+
}
54+
55+
if (sourceJars.isEmpty()) {
56+
throw new IllegalArgumentException("At least one input just must be specified via the --in flag");
57+
}
58+
59+
if (out == null) {
60+
throw new IllegalArgumentException("The output jar location must be specified via the --out flag");
61+
}
62+
63+
Set<Path> tempDirs = new HashSet<>();
64+
Path dir = Files.createTempDirectory("javadocs");
65+
tempDirs.add(dir);
66+
67+
try {
68+
DocumentationTool tool = ToolProvider.getSystemDocumentationTool();
69+
try (StandardJavaFileManager fileManager = tool.getStandardFileManager(null, Locale.getDefault(), StandardCharsets.UTF_8)) {
70+
fileManager.setLocation(DocumentationTool.Location.DOCUMENTATION_OUTPUT, List.of(dir.toFile()));
71+
72+
Set<JavaFileObject> sources = new HashSet<>();
73+
Set<String> topLevelPackages = new HashSet<>();
74+
75+
Path unpackTo = Files.createTempDirectory("unpacked-sources");
76+
tempDirs.add(unpackTo);
77+
Set<String> fileNames = new HashSet<>();
78+
readSourceFiles(unpackTo, fileManager, sourceJars, sources, topLevelPackages, fileNames);
79+
List<String> options = new ArrayList<>();
80+
options.addAll(List.of("-html5", "-notimestamp", "-use", "-quiet", "-Xdoclint:-missing", "-encoding", "UTF8"));
81+
if (!classpath.isEmpty()) {
82+
options.add("-cp");
83+
options.add(classpath.stream().map(Path::toAbsolutePath).map(String::valueOf).collect(Collectors.joining(File.pathSeparator)));
84+
}
85+
86+
Path outputTo = Files.createTempDirectory("output-dir");
87+
tempDirs.add(outputTo);
88+
89+
options.addAll(List.of("-d", outputTo.toAbsolutePath().toString()));
90+
91+
sources.forEach(obj -> options.add(obj.getName()));
92+
93+
Writer writer = new StringWriter();
94+
DocumentationTool.DocumentationTask task = tool.getTask(writer, fileManager, null, null, options, sources);
95+
Boolean result = task.call();
96+
if (result == null || !result) {
97+
System.err.println(writer);
98+
return;
99+
}
100+
101+
try (OutputStream os = Files.newOutputStream(out);
102+
ZipOutputStream zos = new ZipOutputStream(os)) {
103+
Files.walk(outputTo)
104+
.sorted(Comparator.naturalOrder())
105+
.forEachOrdered(path -> {
106+
if (path.equals(outputTo)) {
107+
return;
108+
}
109+
110+
try {
111+
if (Files.isDirectory(path)) {
112+
String name = outputTo.relativize(path) + "/";
113+
ZipEntry entry = new ZipEntry(name);
114+
zos.putNextEntry(entry);
115+
zos.closeEntry();
116+
} else {
117+
String name = outputTo.relativize(path).toString();
118+
ZipEntry entry = new ZipEntry(name);
119+
zos.putNextEntry(entry);
120+
try (InputStream is = Files.newInputStream(path)) {
121+
is.transferTo(zos);
122+
}
123+
zos.closeEntry();
124+
}
125+
} catch (IOException e) {
126+
throw new UncheckedIOException(e);
127+
}
128+
});
129+
}
130+
}
131+
} finally {
132+
tempDirs.forEach(d -> {
133+
try {
134+
Files.walk(d)
135+
.sorted(Comparator.reverseOrder())
136+
.map(Path::toFile)
137+
.forEach(File::delete);
138+
} catch (IOException e) {
139+
throw new UncheckedIOException(e);
140+
}
141+
});
142+
}
143+
}
144+
145+
private static void readSourceFiles(
146+
Path unpackTo,
147+
StandardJavaFileManager fileManager,
148+
Set<Path> sourceJars,
149+
Set<JavaFileObject> sources,
150+
Set<String> topLevelPackages,
151+
Set<String> fileNames) throws IOException {
152+
153+
for (Path jar : sourceJars) {
154+
if (!Files.exists(jar)) {
155+
continue;
156+
}
157+
158+
try (ZipInputStream zis = new ZipInputStream(Files.newInputStream(jar))) {
159+
for (ZipEntry entry = zis.getNextEntry(); entry != null; entry = zis.getNextEntry()) {
160+
String name = entry.getName();
161+
if (!name.endsWith(".java")) {
162+
continue;
163+
}
164+
165+
Path target = unpackTo.resolve(name).normalize();
166+
if (!target.startsWith(unpackTo)) {
167+
throw new IOException("Attempt to write out of working directory");
168+
}
169+
170+
Files.createDirectories(target.getParent());
171+
try (OutputStream out = Files.newOutputStream(target)) {
172+
zis.transferTo(out);
173+
}
174+
175+
fileManager.getJavaFileObjects(target).forEach(sources::add);
176+
177+
String[] segments = name.split("/");
178+
if (segments.length > 0 && !"META-INF".equals(segments[0])) {
179+
topLevelPackages.add(segments[0]);
180+
}
181+
182+
fileNames.add(name);
183+
}
184+
}
185+
}
186+
}
187+
}

java/defs.bzl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
load("//java/private:dist_zip.bzl", _java_dist_zip = "java_dist_zip")
22
load("//java/private:export.bzl", _java_export = "java_export")
3+
load("//java/private:javadoc.bzl", _javadoc = "javadoc")
34
load("//java/private:module.bzl", _java_module = "java_module")
45
load("//java/private:test.bzl", _java_selenium_test_suite = "java_selenium_test_suite", _java_test_suite = "java_test_suite")
56

67
java_dist_zip = _java_dist_zip
78
java_export = _java_export
9+
javadoc = _javadoc
810
java_module = _java_module
911
java_selenium_test_suite = _java_selenium_test_suite
1012
java_test_suite = _java_test_suite

java/private/javadoc.bzl

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
load("//java/private:module.bzl", "JavaModuleInfo")
2+
3+
def _javadoc_impl(ctx):
4+
sources = []
5+
for dep in ctx.attr.deps:
6+
if JavaModuleInfo in dep:
7+
sources.extend(dep[JavaInfo].source_jars)
8+
else:
9+
sources.extend(dep[JavaInfo].source_jars)
10+
11+
jar_file = ctx.actions.declare_file("%s.jar" % ctx.attr.name)
12+
13+
args = ctx.actions.args()
14+
args.add_all(["--out", jar_file])
15+
args.add_all(sources, before_each = "--in")
16+
17+
ctx.actions.run(
18+
executable = ctx.executable._javadoc,
19+
outputs = [jar_file],
20+
inputs = depset(sources),
21+
arguments = [args],
22+
)
23+
24+
return [
25+
DefaultInfo(files = depset([jar_file])),
26+
]
27+
28+
javadoc = rule(
29+
_javadoc_impl,
30+
attrs = {
31+
"deps": attr.label_list(
32+
mandatory = True,
33+
providers = [
34+
[JavaInfo],
35+
],
36+
),
37+
"hide": attr.string_list(),
38+
"_javadoc": attr.label(
39+
default = "//java/client/src/org/openqa/selenium/tools/javadoc",
40+
cfg = "host",
41+
executable = True,
42+
),
43+
},
44+
)

0 commit comments

Comments
 (0)