diff --git a/make/CompileToolsJdk.gmk b/make/CompileToolsJdk.gmk
index 367b60887a1..a671f934998 100644
--- a/make/CompileToolsJdk.gmk
+++ b/make/CompileToolsJdk.gmk
@@ -103,8 +103,8 @@ ifeq ($(ENABLE_PANDOC), true)
SOURCE_FILES := $(TOPDIR)/make/scripts/pandoc-troff-manpage-filter.sh.template, \
OUTPUT_FILE := $(PANDOC_TROFF_MANPAGE_FILTER), \
REPLACEMENTS := \
- @@JJS@@ => $(JJS) ; \
- @@TOPDIR@@ => $(TOPDIR) ; \
+ @@JAVA_SMALL@@ => $(JAVA_SMALL) ; \
+ @@BUILDTOOLS_OUTPUTDIR@@ => $(BUILDTOOLS_OUTPUTDIR) ; \
))
# Created script must be made executable
@@ -126,8 +126,8 @@ ifeq ($(ENABLE_PANDOC), true)
SOURCE_FILES := $(TOPDIR)/make/scripts/pandoc-html-manpage-filter.sh.template, \
OUTPUT_FILE := $(PANDOC_HTML_MANPAGE_FILTER), \
REPLACEMENTS := \
- @@JJS@@ => $(JJS) ; \
- @@TOPDIR@@ => $(TOPDIR) ; \
+ @@JAVA_SMALL@@ => $(JAVA_SMALL) ; \
+ @@BUILDTOOLS_OUTPUTDIR@@ => $(BUILDTOOLS_OUTPUTDIR) ; \
))
# Created script must be made executable
diff --git a/make/Docs.gmk b/make/Docs.gmk
index 00361780d84..898144f6e0a 100644
--- a/make/Docs.gmk
+++ b/make/Docs.gmk
@@ -610,9 +610,9 @@ ifeq ($(ENABLE_PANDOC), true)
# PANDOC_HTML_MANPAGE_FILTER, a wrapper around
# PANDOC_HTML_MANPAGE_FILTER_JAVASCRIPT. This is created by buildtools-jdk.
- # We should also depend on the source javascript filter
- PANDOC_HTML_MANPAGE_FILTER_JAVASCRIPT := \
- $(TOPDIR)/make/scripts/pandoc-html-manpage-filter.js
+ # We should also depend on the source code for the filter
+ PANDOC_HTML_MANPAGE_FILTER_SOURCE := $(call FindFiles, \
+ $(TOPDIR)/make/jdk/src/classes/build/tools/pandocfilter)
$(foreach m, $(ALL_MODULES), \
$(eval MAN_$m := $(call FindModuleManDirs, $m)) \
@@ -632,7 +632,7 @@ ifeq ($(ENABLE_PANDOC), true)
OPTIONS := --toc -V include-before='$(SPECS_TOP)' -V include-after='$(SPECS_BOTTOM_1)', \
POST_PROCESS := $(TOOL_FIXUPPANDOC), \
EXTRA_DEPS := $(PANDOC_HTML_MANPAGE_FILTER) \
- $(PANDOC_HTML_MANPAGE_FILTER_JAVASCRIPT), \
+ $(PANDOC_HTML_MANPAGE_FILTER_SOURCE), \
)) \
$(eval JDK_SPECS_TARGETS += $($($m_$f_NAME))) \
) \
diff --git a/make/autoconf/boot-jdk.m4 b/make/autoconf/boot-jdk.m4
index 593e9df4236..c16cee8266c 100644
--- a/make/autoconf/boot-jdk.m4
+++ b/make/autoconf/boot-jdk.m4
@@ -381,22 +381,6 @@ AC_DEFUN_ONCE([BOOTJDK_SETUP_BOOT_JDK],
BOOTJDK_USE_LOCAL_CDS=false
AC_MSG_RESULT([no, -XX:SharedArchiveFile not supported])
fi
-
- # Check for jjs in bootjdk
- UTIL_SETUP_TOOL(JJS,
- [
- AC_MSG_CHECKING([for jjs in Boot JDK])
- JJS=$BOOT_JDK/bin/jjs
- if test ! -x $JJS; then
- AC_MSG_RESULT(not found)
- JJS=""
- AC_MSG_NOTICE([Cannot use pandoc without jjs])
- ENABLE_PANDOC=false
- else
- AC_MSG_RESULT(ok)
- fi
- AC_SUBST(JJS)
- ])
])
AC_DEFUN_ONCE([BOOTJDK_SETUP_BOOT_JDK_ARGUMENTS],
diff --git a/make/autoconf/spec.gmk.in b/make/autoconf/spec.gmk.in
index ce7f252446c..7b7cf98f157 100644
--- a/make/autoconf/spec.gmk.in
+++ b/make/autoconf/spec.gmk.in
@@ -625,7 +625,6 @@ JAR_CMD:=@JAR@
JLINK_CMD := @JLINK@
JMOD_CMD := @JMOD@
JARSIGNER_CMD:=@JARSIGNER@
-JJS_CMD:=@JJS@
# These variables are meant to be used. They are defined with = instead of := to make
# it possible to override only the *_CMD variables.
JAVA=@FIXPATH@ $(JAVA_CMD) $(JAVA_FLAGS_BIG) $(JAVA_FLAGS)
@@ -637,7 +636,6 @@ JAR=@FIXPATH@ $(JAR_CMD)
JLINK = @FIXPATH@ $(JLINK_CMD)
JMOD = @FIXPATH@ $(JMOD_CMD) $(JAVA_TOOL_FLAGS_SMALL)
JARSIGNER=@FIXPATH@ $(JARSIGNER_CMD)
-JJS=@FIXPATH@ $(JJS_CMD) $(JAVA_TOOL_FLAGS_SMALL)
BUILD_JAVA_FLAGS := @BOOTCYCLE_JVM_ARGS_BIG@
BUILD_JAVA=@FIXPATH@ $(BUILD_JDK)/bin/java $(BUILD_JAVA_FLAGS)
diff --git a/make/common/modules/LauncherCommon.gmk b/make/common/modules/LauncherCommon.gmk
index 8620d48d895..5aa8bce79bb 100644
--- a/make/common/modules/LauncherCommon.gmk
+++ b/make/common/modules/LauncherCommon.gmk
@@ -199,9 +199,9 @@ ifeq ($(call isTargetOsType, unix), true)
# PANDOC_TROFF_MANPAGE_FILTER, a wrapper around
# PANDOC_TROFF_MANPAGE_FILTER_JAVASCRIPT. This is created by buildtools-jdk.
- # We should also depend on the source javascript filter
- PANDOC_TROFF_MANPAGE_FILTER_JAVASCRIPT := \
- $(TOPDIR)/make/scripts/pandoc-troff-manpage-filter.js
+ # We should also depend on the source code for the filter
+ PANDOC_TROFF_MANPAGE_FILTER_SOURCE := $(call FindFiles, \
+ $(TOPDIR)/make/jdk/src/classes/build/tools/pandocfilter)
# The norm in man pages is to display code literals as bold, but pandoc
# "correctly" converts these constructs (encoded in markdown using `...`
@@ -231,7 +231,7 @@ ifeq ($(call isTargetOsType, unix), true)
@@VERSION_SHORT@@ => $(VERSION_SHORT) ; \
@@VERSION_SPECIFICATION@@ => $(VERSION_SPECIFICATION), \
EXTRA_DEPS := $(PANDOC_TROFF_MANPAGE_FILTER) \
- $(PANDOC_TROFF_MANPAGE_FILTER_JAVASCRIPT), \
+ $(PANDOC_TROFF_MANPAGE_FILTER_SOURCE), \
))
TARGETS += $(BUILD_MAN_PAGES)
diff --git a/make/conf/jib-profiles.js b/make/conf/jib-profiles.js
index a070909f397..e95459f5022 100644
--- a/make/conf/jib-profiles.js
+++ b/make/conf/jib-profiles.js
@@ -604,10 +604,6 @@ var getJibProfilesProfiles = function (input, common, data) {
dependencies: [ name + ".jdk" ],
configure_args: [
"--with-boot-jdk=" + input.get(name + ".jdk", "home_path"),
- // Full docs do not currently work with bootcycle build
- // since Nashorn was removed. This negates the
- // --enable-full-docs from the main profile.
- "--enable-full-docs=auto",
]
}
profiles[bootcyclePrebuiltName] = concatObjects(profiles[name],
@@ -765,7 +761,7 @@ var getJibProfilesProfiles = function (input, common, data) {
profiles[cmpBaselineName].make_args = [ "COMPARE_BUILD=CONF=" ];
profiles[cmpBaselineName].configure_args = concat(
profiles[cmpBaselineName].configure_args,
- "--with-hotspot-build-time=n/a",
+ "--with-hotspot-build-time=n/a",
"--disable-precompiled-headers");
// Do not inherit artifact definitions from base profile
delete profiles[cmpBaselineName].artifacts;
diff --git a/make/jdk/src/classes/build/tools/pandocfilter/PandocFilter.java b/make/jdk/src/classes/build/tools/pandocfilter/PandocFilter.java
new file mode 100644
index 00000000000..64eeaaa36df
--- /dev/null
+++ b/make/jdk/src/classes/build/tools/pandocfilter/PandocFilter.java
@@ -0,0 +1,108 @@
+package build.tools.pandocfilter;
+
+import build.tools.pandocfilter.json.JSON;
+import build.tools.pandocfilter.json.JSONArray;
+import build.tools.pandocfilter.json.JSONObject;
+import build.tools.pandocfilter.json.JSONString;
+import build.tools.pandocfilter.json.JSONValue;
+
+import java.io.BufferedReader;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.InputStreamReader;
+import java.util.Map;
+
+public class PandocFilter {
+ /**
+ * Traverse a tree of pandoc format objects, calling callback on each
+ * element, and replacing it if callback returns a new object.
+ *
+ * Inspired by the walk method in
+ * https://github.com/jgm/pandocfilters/blob/master/pandocfilters.py
+ */
+ public JSONValue traverse(JSONValue obj, Callback callback, boolean deep) {
+ if (obj instanceof JSONArray) {
+ JSONArray array = (JSONArray) obj;
+
+ JSONArray processed_array = new JSONArray();
+ for (JSONValue elem : array) {
+ if (elem instanceof JSONObject && elem.contains("t")) {
+ JSONValue replacement = callback.invoke(elem.get("t").asString(), elem.contains("c") ? elem.get("c") : new JSONArray());
+ if (replacement == null) {
+ // no replacement object returned, use original
+ processed_array.add(traverse(elem, callback, deep));
+ } else if (replacement instanceof JSONArray) {
+ // array of objects returned, splice all elements into array
+ JSONArray replacement_array = (JSONArray) replacement;
+ for (JSONValue repl_elem : replacement_array) {
+ processed_array.add(traverse(repl_elem, callback, deep));
+ }
+ } else {
+ // replacement object given, traverse it
+ processed_array.add(traverse(replacement, callback, deep));
+ }
+ } else {
+ processed_array.add(traverse(elem, callback, deep));
+ }
+ }
+ return processed_array;
+ } else if (obj instanceof JSONObject) {
+ if (deep && obj.contains("t")) {
+ JSONValue replacement = callback.invoke(obj.get("t").asString(), obj.contains("c") ? obj.get("c") : new JSONArray());
+ if (replacement != null) {
+ return replacement;
+ }
+ } JSONObject obj_obj = (JSONObject) obj;
+ var processed_obj = new JSONObject();
+ for (String key : obj_obj.keys()) {
+ processed_obj.put(key, traverse(obj_obj.get(key), callback, deep));
+ }
+ return processed_obj;
+ } else {
+ return obj;
+ }
+ }
+
+ public JSONValue createPandocNode(String type, JSONValue content) {
+ if (content == null) {
+ return new JSONObject(Map.of(
+ "t", new JSONString(type)));
+ } else {
+ return new JSONObject(Map.of(
+ "t", new JSONString(type),
+ "c", content));
+ }
+ }
+
+ public JSONValue createPandocNode(String type) {
+ return createPandocNode(type, null);
+ }
+
+ /*
+ * Helper constructors to create pandoc format objects
+ */
+ public JSONValue createSpace() {
+ return createPandocNode("Space");
+ }
+
+ public JSONValue createStr(String string) {
+ return createPandocNode("Str", new JSONString(string));
+ }
+
+ public static JSONValue loadJson(String[] args) throws FileNotFoundException {
+ StringBuffer input = new StringBuffer();
+ InputStreamReader reader;
+ if (args.length > 0)
+ reader = new FileReader(args[0]);
+ else {
+ reader = new InputStreamReader(System.in);
+ }
+ new BufferedReader(reader).lines().forEach(line -> input.append(line));
+
+ return JSON.parse(input.toString());
+ }
+
+ public interface Callback {
+ JSONValue invoke(String type, JSONValue value);
+ }
+}
diff --git a/make/jdk/src/classes/build/tools/pandocfilter/PandocManPageHtmlFilter.java b/make/jdk/src/classes/build/tools/pandocfilter/PandocManPageHtmlFilter.java
new file mode 100644
index 00000000000..2a4165c9bc3
--- /dev/null
+++ b/make/jdk/src/classes/build/tools/pandocfilter/PandocManPageHtmlFilter.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package build.tools.pandocfilter;
+
+import build.tools.pandocfilter.json.JSONArray;
+import build.tools.pandocfilter.json.JSONObject;
+import build.tools.pandocfilter.json.JSONValue;
+
+import java.io.FileNotFoundException;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class PandocManPageHtmlFilter extends PandocFilter {
+
+ private JSONValue MetaInlines(JSONValue value) {
+ return createPandocNode("MetaInlines", value);
+ }
+
+ private JSONValue changeTitle(String type, JSONValue value) {
+ if (type.equals("MetaInlines")) {
+ String subType = value.get(0).get("t").asString();
+ String subContent = value.get(0).get("c").asString();
+ if (subType.equals("Str")) {
+ Pattern pattern = Pattern.compile("^([A-Z0-9]+)\\([0-9]+\\)$");
+ Matcher matcher = pattern.matcher(subContent);
+ if (matcher.find()) {
+ String commandName = matcher.group(1).toLowerCase();
+ return MetaInlines(new JSONArray(
+ createStr("The"), createSpace(),
+ createStr(commandName),
+ createSpace(), createStr("Command")));
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Main function
+ */
+ public static void main(String[] args) throws FileNotFoundException {
+ JSONValue json = loadJson(args);
+
+ PandocManPageHtmlFilter filter = new PandocManPageHtmlFilter();
+
+ JSONValue meta = json.get("meta");
+ if (meta != null && meta instanceof JSONObject) {
+ JSONObject metaobj = (JSONObject) meta;
+ metaobj.remove("date");
+ JSONValue title = meta.get("title");
+ if (title != null) {
+ metaobj.put("title", filter.traverse(title, filter::changeTitle, true));
+ }
+ }
+
+ System.out.println(json);
+ }
+}
diff --git a/make/jdk/src/classes/build/tools/pandocfilter/PandocManPageTroffFilter.java b/make/jdk/src/classes/build/tools/pandocfilter/PandocManPageTroffFilter.java
new file mode 100644
index 00000000000..e7bbc1346f5
--- /dev/null
+++ b/make/jdk/src/classes/build/tools/pandocfilter/PandocManPageTroffFilter.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package build.tools.pandocfilter;
+
+import build.tools.pandocfilter.json.JSONArray;
+import build.tools.pandocfilter.json.JSONValue;
+
+import java.io.FileNotFoundException;
+
+public class PandocManPageTroffFilter extends PandocFilter {
+
+ private JSONValue createStrong(JSONValue value) {
+ return createPandocNode("Strong", value);
+ }
+
+ private JSONValue createHeader(JSONValue value) {
+ return createPandocNode("Header", value);
+ }
+
+ /**
+ * Callback to change all Str texts to upper case
+ */
+ private JSONValue uppercase(String type, JSONValue value) {
+ if (type.equals("Str")) {
+ return createStr(value.asString().toUpperCase());
+ }
+ return null;
+ }
+
+ /**
+ * Main callback function that performs our man page AST rewrites
+ */
+ private JSONValue manpageFilter(String type, JSONValue value) {
+ // If it is a header, decrease the heading level by one, and
+ // if it is a level 1 header, convert it to upper case.
+ if (type.equals("Header")) {
+ JSONArray array = value.asArray();
+ int level = array.get(0).asInt();
+ array.set(0, JSONValue.from(level - 1));
+ if (value.asArray().get(0).asInt() == 1) {
+ return createHeader(traverse(value, this::uppercase, false));
+ }
+ }
+
+ // Man pages does not have superscript. We use it for footnotes, so
+ // enclose in [...] for best representation.
+ if (type.equals("Superscript")) {
+ return new JSONArray(createStr("["), value, createStr("]"));
+ }
+
+ // If it is a link, put the link name in bold. If it is an external
+ // link, put it in brackets. Otherwise, it is either an internal link
+ // (like "#next-heading"), or a relative link to another man page
+ // (like "java.html"), so remove it for man pages.
+ if (type.equals("Link")) {
+ JSONValue target = value.asArray().get(2).asArray().get(0);
+ String targetStr = target.asString();
+ if (targetStr.startsWith("https:") || targetStr.startsWith("http:")) {
+ return new JSONArray(createStrong(value.asArray().get(1)), createSpace(), createStr("[" + targetStr + "]"));
+ } else {
+ return createStrong(value.asArray().get(1));
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Main function
+ */
+ public static void main(String[] args) throws FileNotFoundException {
+ JSONValue json = loadJson(args);
+ build.tools.pandocfilter.PandocManPageTroffFilter filter = new build.tools.pandocfilter.PandocManPageTroffFilter();
+
+ JSONValue transformed_json = filter.traverse(json, filter::manpageFilter, false);
+
+ System.out.println(transformed_json);
+ }
+}
diff --git a/make/jdk/src/classes/build/tools/pandocfilter/json/JSON.java b/make/jdk/src/classes/build/tools/pandocfilter/json/JSON.java
new file mode 100644
index 00000000000..54c5027b7e8
--- /dev/null
+++ b/make/jdk/src/classes/build/tools/pandocfilter/json/JSON.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package build.tools.pandocfilter.json;
+
+public class JSON {
+ public static JSONValue parse(String s) {
+ return new JSONParser().parse(s);
+ }
+
+ public static JSONValue of(int i) {
+ return JSONValue.from(i);
+ }
+
+ public static JSONValue of(long l) {
+ return JSONValue.from(l);
+ }
+
+ public static JSONValue of(double d) {
+ return JSONValue.from(d);
+ }
+
+ public static JSONValue of(boolean b) {
+ return JSONValue.from(b);
+ }
+
+ public static JSONValue of(String s) {
+ return JSONValue.from(s);
+ }
+
+ public static JSONValue of() {
+ return JSONValue.fromNull();
+ }
+
+ public static JSONArray array() {
+ return new JSONArray();
+ }
+
+ public static JSONObject object() {
+ return new JSONObject();
+ }
+}
diff --git a/make/jdk/src/classes/build/tools/pandocfilter/json/JSONArray.java b/make/jdk/src/classes/build/tools/pandocfilter/json/JSONArray.java
new file mode 100644
index 00000000000..05262d89bd5
--- /dev/null
+++ b/make/jdk/src/classes/build/tools/pandocfilter/json/JSONArray.java
@@ -0,0 +1,176 @@
+/*
+ * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package build.tools.pandocfilter.json;
+
+import java.util.*;
+import java.util.stream.Stream;
+
+public class JSONArray implements JSONValue, Iterable {
+ private final List values;
+
+ public JSONArray() {
+ this.values = new ArrayList();
+ }
+
+ public JSONArray(JSONValue[] array) {
+ this.values = new ArrayList(array.length);
+ for (var v : array) {
+ values.add(v);
+ }
+ }
+
+ private void append(JSONValue value) {
+ if (value instanceof JSONArray) {
+ for (var v : value.asArray()) {
+ append(v);
+ }
+ } else {
+ this.values.add(value);
+ }
+ }
+
+ public JSONArray(JSONValue value, JSONValue... values) {
+ this.values = new ArrayList(values.length + 1);
+ append(value);
+ for (var v : values) {
+ append(v);
+ }
+ }
+
+ public JSONArray(List values) {
+ this.values = new ArrayList(values);
+ }
+
+ @Override
+ public boolean isArray() {
+ return true;
+ }
+
+ @Override
+ public JSONArray asArray() {
+ return this;
+ }
+
+ public JSONArray set(int i, boolean value) {
+ values.set(i, JSON.of(value));
+ return this;
+ }
+
+ public JSONArray set(int i, int value) {
+ values.set(i, JSON.of(value));
+ return this;
+ }
+
+ public JSONArray set(int i, long value) {
+ values.set(i, JSON.of(value));
+ return this;
+ }
+
+ public JSONArray set(int i, String value) {
+ values.set(i, JSON.of(value));
+ return this;
+ }
+
+ public JSONArray set(int i, double value) {
+ values.set(i, JSON.of(value));
+ return this;
+ }
+
+ public JSONArray set(int i, JSONValue value) {
+ values.set(i, value);
+ return this;
+ }
+
+ public JSONArray setNull(int i) {
+ values.set(i, JSON.of());
+ return this;
+ }
+
+ public JSONArray add(boolean value) {
+ values.add(JSON.of(value));
+ return this;
+ }
+
+ public JSONArray add(int value) {
+ values.add(JSON.of(value));
+ return this;
+ }
+
+ public JSONArray add(long value) {
+ values.add(JSON.of(value));
+ return this;
+ }
+
+ public JSONArray add(String value) {
+ values.add(JSON.of(value));
+ return this;
+ }
+
+ public JSONArray add(double value) {
+ values.add(JSON.of(value));
+ return this;
+ }
+
+ public JSONArray add(JSONValue value) {
+ values.add(value);
+ return this;
+ }
+
+ public JSONArray addNull() {
+ values.add(JSON.of());
+ return this;
+ }
+
+ public JSONValue get(int i) {
+ return values.get(i);
+ }
+
+ public int size() {
+ return values.size();
+ }
+
+ @Override
+ public String toString() {
+ var builder = new StringBuilder();
+
+ builder.append("[");
+ for (var i = 0; i < size(); i++) {
+ builder.append(get(i).toString());
+ if (i != (size() - 1)) {
+ builder.append(",");
+ }
+ }
+ builder.append("]");
+ return builder.toString();
+ }
+
+ @Override
+ public Stream stream() {
+ return values.stream();
+ }
+
+ @Override
+ public Iterator iterator() {
+ return values.iterator();
+ }
+}
diff --git a/make/jdk/src/classes/build/tools/pandocfilter/json/JSONBoolean.java b/make/jdk/src/classes/build/tools/pandocfilter/json/JSONBoolean.java
new file mode 100644
index 00000000000..dfade3656db
--- /dev/null
+++ b/make/jdk/src/classes/build/tools/pandocfilter/json/JSONBoolean.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package build.tools.pandocfilter.json;
+
+public class JSONBoolean implements JSONValue {
+ private boolean value;
+
+ public JSONBoolean(boolean value) {
+ this.value = value;
+ }
+
+ @Override
+ public boolean isBoolean() {
+ return true;
+ }
+
+ @Override
+ public boolean asBoolean() {
+ return value;
+ }
+
+ @Override
+ public String toString() {
+ return value ? "true" : "false";
+ }
+}
diff --git a/make/jdk/src/classes/build/tools/pandocfilter/json/JSONDecimal.java b/make/jdk/src/classes/build/tools/pandocfilter/json/JSONDecimal.java
new file mode 100644
index 00000000000..f9d165f1d69
--- /dev/null
+++ b/make/jdk/src/classes/build/tools/pandocfilter/json/JSONDecimal.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package build.tools.pandocfilter.json;
+
+public class JSONDecimal implements JSONValue {
+ private double value;
+
+ public JSONDecimal(double value) {
+ this.value = value;
+ }
+
+ @Override
+ public boolean isDouble() {
+ return true;
+ }
+
+ @Override
+ public double asDouble() {
+ return value;
+ }
+
+ @Override
+ public String toString() {
+ return Double.toString(value);
+ }
+}
diff --git a/make/jdk/src/classes/build/tools/pandocfilter/json/JSONNull.java b/make/jdk/src/classes/build/tools/pandocfilter/json/JSONNull.java
new file mode 100644
index 00000000000..03e03452e67
--- /dev/null
+++ b/make/jdk/src/classes/build/tools/pandocfilter/json/JSONNull.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package build.tools.pandocfilter.json;
+
+public class JSONNull implements JSONValue {
+ public JSONNull() {
+ }
+
+ @Override
+ public boolean isNull() {
+ return true;
+ }
+
+ @Override
+ public String asString() {
+ return null;
+ }
+
+ @Override
+ public JSONArray asArray() {
+ return null;
+ }
+
+ @Override
+ public JSONObject asObject() {
+ return null;
+ }
+
+ @Override
+ public String toString() {
+ return "null";
+ }
+}
diff --git a/make/jdk/src/classes/build/tools/pandocfilter/json/JSONNumber.java b/make/jdk/src/classes/build/tools/pandocfilter/json/JSONNumber.java
new file mode 100644
index 00000000000..e5f9a0075c7
--- /dev/null
+++ b/make/jdk/src/classes/build/tools/pandocfilter/json/JSONNumber.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package build.tools.pandocfilter.json;
+
+public class JSONNumber implements JSONValue {
+ private long value;
+
+ public JSONNumber(int value) {
+ this.value = value;
+ }
+
+ public JSONNumber(long value) {
+ this.value = value;
+ }
+
+ @Override
+ public boolean isInt() {
+ return true;
+ }
+
+ @Override
+ public boolean isLong() {
+ return true;
+ }
+
+ @Override
+ public int asInt() {
+ return Math.toIntExact(value);
+ }
+
+ @Override
+ public long asLong() {
+ return value;
+ }
+
+ @Override
+ public String toString() {
+ return Long.toString(value);
+ }
+}
diff --git a/make/jdk/src/classes/build/tools/pandocfilter/json/JSONObject.java b/make/jdk/src/classes/build/tools/pandocfilter/json/JSONObject.java
new file mode 100644
index 00000000000..962356d5a79
--- /dev/null
+++ b/make/jdk/src/classes/build/tools/pandocfilter/json/JSONObject.java
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package build.tools.pandocfilter.json;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+public class JSONObject implements JSONValue {
+ public static class Field {
+ private final String name;
+ private final JSONValue value;
+
+ private Field(String name, JSONValue value) {
+ this.name = name;
+ this.value = value;
+ }
+
+ public String name() {
+ return name;
+ }
+
+ public JSONValue value() {
+ return value;
+ }
+ }
+
+ private final Map value;
+
+ public JSONObject() {
+ this.value = new HashMap();
+ }
+
+ public JSONObject(Map map) {
+ this.value = new HashMap(map);
+ }
+
+ @Override
+ public boolean isObject() {
+ return true;
+ }
+
+ @Override
+ public JSONObject asObject() {
+ return this;
+ }
+
+ public JSONObject put(String k, boolean v) {
+ value.put(k, JSON.of(v));
+ return this;
+ }
+
+ public JSONObject put(String k, int v) {
+ value.put(k, JSON.of(v));
+ return this;
+ }
+
+ public JSONObject put(String k, long v) {
+ value.put(k, JSON.of(v));
+ return this;
+ }
+
+ public JSONObject put(String k, String v) {
+ value.put(k, JSON.of(v));
+ return this;
+ }
+
+ public JSONObject put(String k, double v) {
+ value.put(k, JSON.of(v));
+ return this;
+ }
+
+ public JSONObject put(String k, JSONArray v) {
+ value.put(k, v);
+ return this;
+ }
+
+ public JSONObject put(String k, JSONObject v) {
+ value.put(k, v);
+ return this;
+ }
+
+ public JSONObject put(String k, JSONValue v) {
+ value.put(k, v);
+ return this;
+ }
+
+ public JSONObject putNull(String k) {
+ value.put(k, JSON.of());
+ return this;
+ }
+
+ public JSONValue remove(String k) {
+ return value.remove(k);
+ }
+
+ public JSONValue get(String k) {
+ return value.get(k);
+ }
+
+ public List fields() {
+ return value.entrySet()
+ .stream()
+ .map(e -> new Field(e.getKey(), e.getValue()))
+ .collect(Collectors.toList());
+ }
+
+ public boolean contains(String field) {
+ return value.containsKey(field);
+ }
+
+ public Set keys() {
+ return value.keySet();
+ }
+
+ @Override
+ public String toString() {
+ var builder = new StringBuilder();
+ builder.append("{");
+ for (var key : value.keySet()) {
+ builder.append("\"");
+ builder.append(key);
+ builder.append("\":");
+ builder.append(value.get(key).toString());
+ builder.append(",");
+ }
+
+ var end = builder.length() - 1;
+ if (builder.charAt(end) == ',') {
+ builder.deleteCharAt(end);
+ }
+
+ builder.append("}");
+ return builder.toString();
+ }
+}
diff --git a/make/jdk/src/classes/build/tools/pandocfilter/json/JSONParser.java b/make/jdk/src/classes/build/tools/pandocfilter/json/JSONParser.java
new file mode 100644
index 00000000000..d6ed9d4022b
--- /dev/null
+++ b/make/jdk/src/classes/build/tools/pandocfilter/json/JSONParser.java
@@ -0,0 +1,391 @@
+/*
+ * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package build.tools.pandocfilter.json;
+
+import java.util.*;
+
+class JSONParser {
+ private int pos = 0;
+ private String input;
+
+ JSONParser() {
+ }
+
+ private IllegalStateException failure(String message) {
+ return new IllegalStateException(String.format("[%d]: %s : %s", pos, message, input));
+ }
+
+ private char current() {
+ return input.charAt(pos);
+ }
+
+ private void advance() {
+ pos++;
+ }
+
+ private boolean hasInput() {
+ return pos < input.length();
+ }
+
+ private void expectMoreInput(String message) {
+ if (!hasInput()) {
+ throw failure(message);
+ }
+ }
+
+ private char next(String message) {
+ advance();
+ if (!hasInput()) {
+ throw failure(message);
+ }
+ return current();
+ }
+
+
+ private void expect(char c) {
+ var msg = String.format("Expected character %c", c);
+
+ var n = next(msg);
+ if (n != c) {
+ throw failure(msg);
+ }
+ }
+
+ private void assume(char c, String message) {
+ expectMoreInput(message);
+ if (current() != c) {
+ throw failure(message);
+ }
+ }
+
+ private JSONBoolean parseBoolean() {
+ if (current() == 't') {
+ expect('r');
+ expect('u');
+ expect('e');
+ advance();
+ return new JSONBoolean(true);
+ }
+
+ if (current() == 'f') {
+ expect('a');
+ expect('l');
+ expect('s');
+ expect('e');
+ advance();
+ return new JSONBoolean(false);
+ }
+
+ throw failure("a boolean can only be 'true' or 'false'");
+ }
+
+ private JSONValue parseNumber() {
+ var isInteger = true;
+ var builder = new StringBuilder();
+
+ if (current() == '-') {
+ builder.append(current());
+ advance();
+ expectMoreInput("a number cannot consist of only '-'");
+ }
+
+ if (current() == '0') {
+ builder.append(current());
+ advance();
+
+ if (hasInput() && current() == '.') {
+ isInteger = false;
+ builder.append(current());
+ advance();
+
+ expectMoreInput("a number cannot end with '.'");
+
+ if (!isDigit(current())) {
+ throw failure("must be at least one digit after '.'");
+ }
+
+ while (hasInput() && isDigit(current())) {
+ builder.append(current());
+ advance();
+ }
+ }
+ } else {
+ while (hasInput() && isDigit(current())) {
+ builder.append(current());
+ advance();
+ }
+
+ if (hasInput() && current() == '.') {
+ isInteger = false;
+ builder.append(current());
+ advance();
+
+ expectMoreInput("a number cannot end with '.'");
+
+ if (!isDigit(current())) {
+ throw failure("must be at least one digit after '.'");
+ }
+
+ while (hasInput() && isDigit(current())) {
+ builder.append(current());
+ advance();
+ }
+ }
+ }
+
+ if (hasInput() && (current() == 'e' || current() == 'E')) {
+ isInteger = false;
+
+ builder.append(current());
+ advance();
+ expectMoreInput("a number cannot end with 'e' or 'E'");
+
+ if (current() == '+' || current() == '-') {
+ builder.append(current());
+ advance();
+ }
+
+ if (!isDigit(current())) {
+ throw failure("a digit must follow {'e','E'}{'+','-'}");
+ }
+
+ while (hasInput() && isDigit(current())) {
+ builder.append(current());
+ advance();
+ }
+ }
+
+ var value = builder.toString();
+ return isInteger ? new JSONNumber(Long.parseLong(value)) :
+ new JSONDecimal(Double.parseDouble(value));
+
+ }
+
+ private JSONString parseString() {
+ var missingEndChar = "string is not terminated with '\"'";
+ var builder = new StringBuilder();
+ for (var c = next(missingEndChar); c != '"'; c = next(missingEndChar)) {
+ if (c == '\\') {
+ var n = next(missingEndChar);
+ switch (n) {
+ case '"':
+ builder.append("\"");
+ break;
+ case '\\':
+ builder.append("\\");
+ break;
+ case '/':
+ builder.append("/");
+ break;
+ case 'b':
+ builder.append("\b");
+ break;
+ case 'f':
+ builder.append("\f");
+ break;
+ case 'n':
+ builder.append("\n");
+ break;
+ case 'r':
+ builder.append("\r");
+ break;
+ case 't':
+ builder.append("\t");
+ break;
+ case 'u':
+ var u1 = next(missingEndChar);
+ var u2 = next(missingEndChar);
+ var u3 = next(missingEndChar);
+ var u4 = next(missingEndChar);
+ var cp = Integer.parseInt(String.format("%c%c%c%c", u1, u2, u3, u4), 16);
+ builder.append(new String(new int[]{cp}, 0, 1));
+ break;
+ default:
+ throw failure(String.format("Unexpected escaped character '%c'", n));
+ }
+ } else {
+ builder.append(c);
+ }
+ }
+
+ advance(); // step beyond closing "
+ return new JSONString(builder.toString());
+ }
+
+ private JSONArray parseArray() {
+ var error = "array is not terminated with ']'";
+ var list = new ArrayList();
+
+ advance(); // step beyond opening '['
+ consumeWhitespace();
+ expectMoreInput(error);
+
+ while (current() != ']') {
+ var val = parseValue();
+ list.add(val);
+
+ expectMoreInput(error);
+ if (current() == ',') {
+ advance();
+ }
+ expectMoreInput(error);
+ }
+
+ advance(); // step beyond closing ']'
+ return new JSONArray(list.toArray(new JSONValue[0]));
+ }
+
+ public JSONNull parseNull() {
+ expect('u');
+ expect('l');
+ expect('l');
+ advance();
+ return new JSONNull();
+ }
+
+ public JSONObject parseObject() {
+ var error = "object is not terminated with '}'";
+ var map = new HashMap();
+
+ advance(); // step beyond opening '{'
+ consumeWhitespace();
+ expectMoreInput(error);
+
+ while (current() != '}') {
+ var key = parseValue();
+ if (!(key instanceof JSONString)) {
+ throw failure("a field must of type string");
+ }
+
+ if (!hasInput() || current() != ':') {
+ throw failure("a field must be followed by ':'");
+ }
+ advance(); // skip ':'
+
+ var val = parseValue();
+ map.put(key.asString(), val);
+
+ expectMoreInput(error);
+ if (current() == ',') {
+ advance();
+ }
+ expectMoreInput(error);
+ }
+
+ advance(); // step beyond '}'
+ return new JSONObject(map);
+ }
+
+ private boolean isDigit(char c) {
+ return c == '0' ||
+ c == '1' ||
+ c == '2' ||
+ c == '3' ||
+ c == '4' ||
+ c == '5' ||
+ c == '6' ||
+ c == '7' ||
+ c == '8' ||
+ c == '9';
+ }
+
+ private boolean isStartOfNumber(char c) {
+ return isDigit(c) || c == '-';
+ }
+
+ private boolean isStartOfString(char c) {
+ return c == '"';
+ }
+
+ private boolean isStartOfBoolean(char c) {
+ return c == 't' || c == 'f';
+ }
+
+ private boolean isStartOfArray(char c) {
+ return c == '[';
+ }
+
+ private boolean isStartOfNull(char c) {
+ return c == 'n';
+ }
+
+ private boolean isWhitespace(char c) {
+ return c == '\r' ||
+ c == '\n' ||
+ c == '\t' ||
+ c == ' ';
+ }
+
+ private boolean isStartOfObject(char c) {
+ return c == '{';
+ }
+
+ private void consumeWhitespace() {
+ while (hasInput() && isWhitespace(current())) {
+ advance();
+ }
+ }
+
+ public JSONValue parseValue() {
+ JSONValue ret = null;
+
+ consumeWhitespace();
+ if (hasInput()) {
+ var c = current();
+
+ if (isStartOfNumber(c)) {
+ ret = parseNumber();
+ } else if (isStartOfString(c)) {
+ ret = parseString();
+ } else if (isStartOfBoolean(c)) {
+ ret = parseBoolean();
+ } else if (isStartOfArray(c)) {
+ ret = parseArray();
+ } else if (isStartOfNull(c)) {
+ ret = parseNull();
+ } else if (isStartOfObject(c)) {
+ ret = parseObject();
+ } else {
+ throw failure("not a valid start of a JSON value");
+ }
+ }
+ consumeWhitespace();
+
+ return ret;
+ }
+
+ public JSONValue parse(String s) {
+ if (s == null || s.equals("")) {
+ return null;
+ }
+
+ pos = 0;
+ input = s;
+
+ var result = parseValue();
+ if (hasInput()) {
+ throw failure("can only have one top-level JSON value");
+ }
+ return result;
+ }
+}
diff --git a/make/jdk/src/classes/build/tools/pandocfilter/json/JSONString.java b/make/jdk/src/classes/build/tools/pandocfilter/json/JSONString.java
new file mode 100644
index 00000000000..97ca646232f
--- /dev/null
+++ b/make/jdk/src/classes/build/tools/pandocfilter/json/JSONString.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package build.tools.pandocfilter.json;
+
+public class JSONString implements JSONValue {
+ private String value;
+
+ public JSONString(String value) {
+ this.value = value;
+ }
+
+ @Override
+ public boolean isString() {
+ return true;
+ }
+
+ @Override
+ public String asString() {
+ return value;
+ }
+
+ @Override
+ public String toString() {
+ var builder = new StringBuilder();
+ builder.append("\"");
+
+ for (var i = 0; i < value.length(); i++) {
+ var c = value.charAt(i);
+
+ switch (c) {
+ case '"':
+ builder.append("\\\"");
+ break;
+ case '\\':
+ builder.append("\\\\");
+ break;
+ case '/':
+ builder.append("\\/");
+ break;
+ case '\b':
+ builder.append("\\b");
+ break;
+ case '\f':
+ builder.append("\\f");
+ break;
+ case '\n':
+ builder.append("\\n");
+ break;
+ case '\r':
+ builder.append("\\r");
+ break;
+ case '\t':
+ builder.append("\\t");
+ break;
+ default:
+ builder.append(c);
+ break;
+ }
+ }
+
+ builder.append("\"");
+ return builder.toString();
+ }
+}
diff --git a/make/jdk/src/classes/build/tools/pandocfilter/json/JSONValue.java b/make/jdk/src/classes/build/tools/pandocfilter/json/JSONValue.java
new file mode 100644
index 00000000000..7d1d83b5c8d
--- /dev/null
+++ b/make/jdk/src/classes/build/tools/pandocfilter/json/JSONValue.java
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package build.tools.pandocfilter.json;
+
+import java.util.stream.Stream;
+import java.util.List;
+
+public interface JSONValue {
+ default int asInt() {
+ throw new IllegalStateException("Unsupported conversion to int");
+ }
+
+ default long asLong() {
+ throw new IllegalStateException("Unsupported conversion to long");
+ }
+
+ default double asDouble() {
+ throw new IllegalStateException("Unsupported conversion to double");
+ }
+
+ default String asString() {
+ throw new IllegalStateException("Unsupported conversion to String");
+ }
+
+ default boolean asBoolean() {
+ throw new IllegalStateException("Unsupported conversion to boolean");
+ }
+
+ default JSONArray asArray() {
+ throw new IllegalStateException("Unsupported conversion to array");
+ }
+
+ default JSONObject asObject() {
+ throw new IllegalStateException("Unsupported conversion to object");
+ }
+
+ default boolean isInt() {
+ return false;
+ }
+
+ default boolean isLong() {
+ return false;
+ }
+
+ default boolean isDouble() {
+ return false;
+ }
+
+ default boolean isString() {
+ return false;
+ }
+
+ default boolean isBoolean() {
+ return false;
+ }
+
+ default boolean isArray() {
+ return false;
+ }
+
+ default boolean isObject() {
+ return false;
+ }
+
+ default boolean isNull() {
+ return false;
+ }
+
+ default List fields() {
+ return asObject().fields();
+ }
+
+ default boolean contains(String key) {
+ return asObject().contains(key);
+ }
+
+ default JSONValue get(String key) {
+ return asObject().get(key);
+ }
+
+ default JSONValue get(int i) {
+ return asArray().get(i);
+ }
+
+ default Stream stream() {
+ return Stream.of(this);
+ }
+
+ static JSONValue from(int i) {
+ return new JSONNumber(i);
+ }
+
+ static JSONValue from(long l) {
+ return new JSONNumber(l);
+ }
+
+ static JSONValue from(double d) {
+ return new JSONDecimal(d);
+ }
+
+ static JSONValue from(boolean b) {
+ return new JSONBoolean(b);
+ }
+
+ static JSONValue from(String s) {
+ return new JSONString(s);
+ }
+
+ static JSONValue fromNull() {
+ return new JSONNull();
+ }
+}
diff --git a/make/scripts/pandoc-html-manpage-filter.js b/make/scripts/pandoc-html-manpage-filter.js
deleted file mode 100644
index a7c671a078c..00000000000
--- a/make/scripts/pandoc-html-manpage-filter.js
+++ /dev/null
@@ -1,125 +0,0 @@
-//
-// Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
-// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-//
-// This code is free software; you can redistribute it and/or modify it
-// under the terms of the GNU General Public License version 2 only, as
-// published by the Free Software Foundation.
-//
-// This code is distributed in the hope that it will be useful, but WITHOUT
-// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-// version 2 for more details (a copy is included in the LICENSE file that
-// accompanied this code).
-//
-// You should have received a copy of the GNU General Public License version
-// 2 along with this work; if not, write to the Free Software Foundation,
-// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-//
-// Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-// or visit www.oracle.com if you need additional information or have any
-// questions.
-//
-
-//
-// Traverse a tree of pandoc format objects, calling callback on each
-// element, and replacing it if callback returns a new object.
-//
-// Inspired by the walk method in
-// https://github.com/jgm/pandocfilters/blob/master/pandocfilters.py
-//
-function traverse(obj, callback) {
- if (Array.isArray(obj)) {
- var processed_array = [];
- obj.forEach(function(elem) {
- if (elem === Object(elem) && elem.t) {
- var replacement = callback(elem.t, elem.c || []);
- if (!replacement) {
- // no replacement object returned, use original
- processed_array.push(traverse(elem, callback));
- } else if (Array.isArray(replacement)) {
- // array of objects returned, splice all elements into array
- replacement.forEach(function(repl_elem) {
- processed_array.push(traverse(repl_elem, callback));
- })
- } else {
- // replacement object given, traverse it
- processed_array.push(traverse(replacement, callback));
- }
- } else {
- processed_array.push(traverse(elem, callback));
- }
- })
- return processed_array;
- } else if (obj === Object(obj)) {
- if (obj.t) {
- var replacement = callback(obj.t, obj.c || []);
- if (replacement) {
- return replacement;
- }
- }
- var processed_obj = {};
- Object.keys(obj).forEach(function(key) {
- processed_obj[key] = traverse(obj[key], callback);
- })
- return processed_obj;
- } else {
- return obj;
- }
-}
-
-//
-// Helper constructors to create pandoc format objects
-//
-function Space() {
- return { 't': 'Space' };
-}
-
-function Str(value) {
- return { 't': 'Str', 'c': value };
-}
-
-function MetaInlines(value) {
- return { 't': 'MetaInlines', 'c': value };
-}
-
-function change_title(type, value) {
- if (type === 'MetaInlines') {
- if (value[0].t === 'Str') {
- var match = value[0].c.match(/^([A-Z0-9]+)\([0-9]+\)$/);
- if (match) {
- return MetaInlines([
- Str("The"), Space(),
- Str(match[1].toLowerCase()),
- Space(), Str("Command")
- ]);
- }
- }
- }
-}
-
-//
-// Main function
-//
-function main() {
- var input = "";
- while (line = readLine()) {
- input = input.concat(line);
- }
-
- var json = JSON.parse(input);
-
- var meta = json.meta;
- if (meta) {
- meta.date = undefined;
- var title = meta.title;
- if (meta.title) {
- meta.title = traverse(meta.title, change_title);
- }
- }
-
- print(JSON.stringify(json));
-}
-
-// ... and execute it
-main();
diff --git a/make/scripts/pandoc-html-manpage-filter.sh.template b/make/scripts/pandoc-html-manpage-filter.sh.template
index 9f906eaa389..6f9612513c0 100644
--- a/make/scripts/pandoc-html-manpage-filter.sh.template
+++ b/make/scripts/pandoc-html-manpage-filter.sh.template
@@ -22,7 +22,7 @@
# questions.
#
-# Simple wrapper script to call Nashorn with the javascript pandoc filter
+# Simple wrapper script to call Java with the pandoc filter
-@@JJS@@ -scripting \
- "@@TOPDIR@@/make/scripts/pandoc-html-manpage-filter.js" 2> /dev/null
+@@JAVA_SMALL@@ -cp @@BUILDTOOLS_OUTPUTDIR@@/jdk_tools_classes \
+ build.tools.pandocfilter.PandocManPageHtmlFilter
diff --git a/make/scripts/pandoc-troff-manpage-filter.js b/make/scripts/pandoc-troff-manpage-filter.js
deleted file mode 100644
index d1b20630a48..00000000000
--- a/make/scripts/pandoc-troff-manpage-filter.js
+++ /dev/null
@@ -1,142 +0,0 @@
-//
-// Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
-// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-//
-// This code is free software; you can redistribute it and/or modify it
-// under the terms of the GNU General Public License version 2 only, as
-// published by the Free Software Foundation.
-//
-// This code is distributed in the hope that it will be useful, but WITHOUT
-// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-// version 2 for more details (a copy is included in the LICENSE file that
-// accompanied this code).
-//
-// You should have received a copy of the GNU General Public License version
-// 2 along with this work; if not, write to the Free Software Foundation,
-// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-//
-// Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-// or visit www.oracle.com if you need additional information or have any
-// questions.
-//
-
-//
-// Traverse a tree of pandoc format objects, calling callback on each
-// element, and replacing it if callback returns a new object.
-//
-// Inspired by the walk method in
-// https://github.com/jgm/pandocfilters/blob/master/pandocfilters.py
-//
-function traverse(obj, callback) {
- if (Array.isArray(obj)) {
- var processed_array = [];
- obj.forEach(function(elem) {
- if (elem === Object(elem) && elem.t) {
- var replacement = callback(elem.t, elem.c || []);
- if (!replacement) {
- // no replacement object returned, use original
- processed_array.push(traverse(elem, callback));
- } else if (Array.isArray(replacement)) {
- // array of objects returned, splice all elements into array
- replacement.forEach(function(repl_elem) {
- processed_array.push(traverse(repl_elem, callback));
- })
- } else {
- // replacement object given, traverse it
- processed_array.push(traverse(replacement, callback));
- }
- } else {
- processed_array.push(traverse(elem, callback));
- }
- })
- return processed_array;
- } else if (obj === Object(obj)) {
- var processed_obj = {};
- Object.keys(obj).forEach(function(key) {
- processed_obj[key] = traverse(obj[key], callback);
- })
- return processed_obj;
- } else {
- return obj;
- }
-}
-
-//
-// Helper constructors to create pandoc format objects
-//
-function Space() {
- return { 't': 'Space', 'c': [] };
-}
-
-function Str(value) {
- return { 't': 'Str', 'c': value };
-}
-
-function Strong(value) {
- return { 't': 'Strong', 'c': value };
-}
-
-function Header(value) {
- return { 't': 'Header', 'c': value };
-}
-
-//
-// Callback to change all Str texts to upper case
-//
-function uppercase(type, value) {
- if (type === 'Str') {
- return Str(value.toUpperCase());
- }
-}
-
-//
-// Main callback function that performs our man page AST rewrites
-//
-function manpage_filter(type, value) {
- // If it is a header, decrease the heading level by one, and
- // if it is a level 1 header, convert it to upper case.
- if (type === 'Header') {
- value[0] = Math.max(1, value[0] - 1);
- if (value[0] == 1) {
- return Header(traverse(value, uppercase));
- }
- }
-
- // Man pages does not have superscript. We use it for footnotes, so
- // enclose in [...] for best representation.
- if (type === 'Superscript') {
- return [ Str('['), value[0], Str(']') ];
- }
-
- // If it is a link, put the link name in bold. If it is an external
- // link, put it in brackets. Otherwise, it is either an internal link
- // (like "#next-heading"), or a relative link to another man page
- // (like "java.html"), so remove it for man pages.
- if (type === 'Link') {
- var target = value[2][0];
- if (target.match(/^http[s]?:/)) {
- return [ Strong(value[1]), Space(), Str('[' + target + ']') ];
- } else {
- return Strong(value[1]);
- }
- }
-}
-
-//
-// Main function
-//
-function main() {
- var input = "";
- while (line = readLine()) {
- input = input.concat(line);
- }
- var json = JSON.parse(input);
-
- var transformed_json = traverse(json, manpage_filter);
-
- print(JSON.stringify(transformed_json));
-}
-
-// ... and execute it
-main();
diff --git a/make/scripts/pandoc-troff-manpage-filter.sh.template b/make/scripts/pandoc-troff-manpage-filter.sh.template
index c4f9999ed6c..b2aaec0c043 100644
--- a/make/scripts/pandoc-troff-manpage-filter.sh.template
+++ b/make/scripts/pandoc-troff-manpage-filter.sh.template
@@ -22,7 +22,7 @@
# questions.
#
-# Simple wrapper script to call Nashorn with the javascript pandoc filter
+# Simple wrapper script to call Java with the pandoc filter
-@@JJS@@ -scripting \
- "@@TOPDIR@@/make/scripts/pandoc-troff-manpage-filter.js" 2> /dev/null
+@@JAVA_SMALL@@ -cp @@BUILDTOOLS_OUTPUTDIR@@/jdk_tools_classes \
+ build.tools.pandocfilter.PandocManPageTroffFilter