See More

/* * Copyright 2023 Red Hat * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /// usr/bin/env jbang "$0" "$@" ; exit $? //JAVA 25 static class SourceSpec { final String globSuffix; final Path relativeDir; SourceSpec(String globSuffix, Path relativeDir) { this.globSuffix = globSuffix; this.relativeDir = relativeDir; } } static final String PACKAGE_NAME = "org.patternfly.showcase"; static final String CLASS_NAME = "Code"; static final String TARGET = "src/main/java"; static final String START_COMMENT = "// @code-start:"; static final String END_COMMENT = "// @code-end:"; static final List SOURCES = Arrays.asList( new SourceSpec("*Component.java", Paths.get("src/main/java/org/patternfly/showcase/component")), new SourceSpec("*Extension.java", Paths.get("src/main/java/org/patternfly/showcase/extension")), new SourceSpec("*Layout.java", Paths.get("src/main/java/org/patternfly/showcase/layout")), new SourceSpec("*Chart.java", Paths.get("src/main/java/org/patternfly/showcase/chart")) ); void main(String... args) throws IOException { if (args.length == 0 || args[0] == null || args[0].isEmpty()) { System.err.println("Missing base directory!"); System.exit(1); } Path base = Paths.get(args[0]).toAbsolutePath().normalize(); Path targetPath = base.resolve(TARGET).resolve(PACKAGE_NAME.replace('.', '/')); Files.createDirectories(targetPath); File javaSource = targetPath.resolve(CLASS_NAME + ".java").toFile(); if (javaSource.exists() && !javaSource.delete()) { throw new IOException("Unable to delete existing file: " + javaSource); } StringBuilder out = new StringBuilder(); startClass(out); int counter = processSnippets(base, out); endClass(out); Files.write(javaSource.toPath(), out.toString().getBytes(StandardCharsets.UTF_8)); IO.println("Processed " + counter + " code snippets"); } void startClass(StringBuilder out) { out.append("package ").append(PACKAGE_NAME).append(";\n\n") .append("import java.util.Map;\n") .append("import java.util.HashMap;\n\n") .append("import javax.annotation.processing.Generated;\n\n") .append("/*\n") .append(" * WARNING! This class is generated. Do not modify.\n") .append(" */\n") .append("@Generated(\"code.java\")\n") .append("public final class ").append(CLASS_NAME).append(" {\n\n") .append(" private static final Map snippets = new HashMap<>();\n\n") .append(" static {"); } int processSnippets(Path base, StringBuilder out) throws IOException { int counter = 0; for (SourceSpec spec : SOURCES) { Path dir = base.resolve(spec.relativeDir); if (!Files.isDirectory(dir)) { continue; } final Predicate nameMatches = globPredicate(spec.globSuffix); List files = new ArrayList<>(); try (Stream stream = Files.list(dir)) { stream.filter(p -> Files.isRegularFile(p) && nameMatches.test(p.getFileName().toString())) .forEach(files::add); } files.sort(java.util.Comparator.naturalOrder()); for (Path p : files) { counter += extractFromFile(p, out); } } return counter; } int extractFromFile(Path file, StringBuilder out) throws IOException { String name = ""; boolean collectCode = false; int leadingWhitespace = 0; List code = new ArrayList<>(); int counter = 0; try (BufferedReader reader = new BufferedReader( new InputStreamReader(new FileInputStream(file.toFile()), StandardCharsets.UTF_8))) { String line; while ((line = reader.readLine()) != null) { if (line.contains(START_COMMENT)) { leadingWhitespace = line.indexOf(START_COMMENT); name = line.substring(line.indexOf(START_COMMENT) + START_COMMENT.length()); collectCode = true; } else if (collectCode) { if (line.contains(END_COMMENT + name)) { addSnippet(out, name, code); counter++; // reset name = ""; collectCode = false; leadingWhitespace = 0; code.clear(); } else { if (line.length() < leadingWhitespace) { code.add(line); } else { code.add(line.substring(leadingWhitespace)); } } } } } return counter; } void addSnippet(StringBuilder out, String name, List code) { out.append("\n snippets.put(\"") .append(escapeJava(name)) .append("\", \"") .append(escapeJava(String.join("\n", code))) .append("\");"); } void endClass(StringBuilder out) { out.append("\n }\n\n") .append(" public static String code(String name) {\n") .append(" return snippets.getOrDefault(name, \"n/a\");\n") .append(" }\n") .append("}\n"); } String escapeJava(String in) { if (in == null) {return "";} StringBuilder sb = new StringBuilder(in.length()); for (int i = 0; i < in.length(); i++) { char c = in.charAt(i); switch (c) { case '"': sb.append("\\\""); break; case '\\': sb.append("\\\\"); break; case '\r': sb.append("\\r"); break; case '\n': sb.append("\\n"); break; case '\t': sb.append("\\t"); break; default: sb.append(c); } } return sb.toString(); } Predicate globPredicate(String globSuffix) { // globSuffix like "*Component.java" -> endsWith("Component.java") if (globSuffix.startsWith("*")) { String suffix = globSuffix.substring(1); return name -> name.endsWith(suffix); } return name -> name.equals(globSuffix); }