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