Skip to content

Commit

Permalink
feat: add manifest-to-markdown renderer (eclipse-edc#166)
Browse files Browse the repository at this point in the history
* feat: add JSON -> Markdown renderer

* rename methods

* cleanup, tests

* copyright headers
  • Loading branch information
paullatzelsperger authored Aug 1, 2023
1 parent 0190b53 commit fe44324
Show file tree
Hide file tree
Showing 22 changed files with 5,545 additions and 21 deletions.
15 changes: 6 additions & 9 deletions DEPENDENCIES
Original file line number Diff line number Diff line change
@@ -1,23 +1,19 @@
maven/mavencentral/com.autonomousapps/antlr/4.10.1.3, , restricted, clearlydefined
maven/mavencentral/com.autonomousapps/asm-relocated/9.4.0.1, , restricted, clearlydefined
maven/mavencentral/com.autonomousapps/dependency-analysis-gradle-plugin/1.20.0, , restricted, clearlydefined
maven/mavencentral/com.autonomousapps/graph-support/0.1, , restricted, clearlydefined
maven/mavencentral/com.autonomousapps/graph-support/0.1, Apache-2.0, approved, #9666
maven/mavencentral/com.fasterxml.jackson.core/jackson-annotations/2.11.1, Apache-2.0, approved, CQ23491
maven/mavencentral/com.fasterxml.jackson.core/jackson-annotations/2.14.2, Apache-2.0, approved, #5303
maven/mavencentral/com.fasterxml.jackson.core/jackson-annotations/2.15.2, Apache-2.0, approved, #7947
maven/mavencentral/com.fasterxml.jackson.core/jackson-core/2.14.2, Apache-2.0 AND MIT, approved, #4303
maven/mavencentral/com.fasterxml.jackson.core/jackson-core/2.15.2, MIT AND Apache-2.0, approved, #7932
maven/mavencentral/com.fasterxml.jackson.core/jackson-databind/2.11.0, Apache-2.0, approved, CQ23093
maven/mavencentral/com.fasterxml.jackson.core/jackson-databind/2.11.1, Apache-2.0, approved, CQ23093
maven/mavencentral/com.fasterxml.jackson.core/jackson-databind/2.13.1, Apache-2.0, approved, #2134
maven/mavencentral/com.fasterxml.jackson.core/jackson-databind/2.14.2, Apache-2.0, approved, #4105
maven/mavencentral/com.fasterxml.jackson.core/jackson-databind/2.15.2, Apache-2.0, approved, #7934
maven/mavencentral/com.fasterxml.jackson.core/jackson-databind/2.2.3, Apache-2.0 OR (Apache-2.0 AND LGPL-2.1), restricted, clearlydefined
maven/mavencentral/com.fasterxml.jackson.dataformat/jackson-dataformat-yaml/2.11.1, Apache-2.0, approved, CQ23094
maven/mavencentral/com.fasterxml.jackson.dataformat/jackson-dataformat-yaml/2.13.1, Apache-2.0, approved, #2566
maven/mavencentral/com.fasterxml.jackson.dataformat/jackson-dataformat-yaml/2.15.2, Apache-2.0, approved, #8802
maven/mavencentral/com.fasterxml.jackson.datatype/jackson-datatype-jsr310/2.11.1, Apache-2.0, approved, clearlydefined
maven/mavencentral/com.fasterxml.jackson.datatype/jackson-datatype-jsr310/2.14.2, Apache-2.0, approved, #4699
maven/mavencentral/com.fasterxml.jackson.datatype/jackson-datatype-jsr310/2.15.2, Apache-2.0, approved, #7930
maven/mavencentral/com.fasterxml.jackson/jackson-bom/2.15.2, Apache-2.0, approved, #7929
maven/mavencentral/com.fasterxml/classmate/1.3.1, Apache-2.0, approved, CQ10239
Expand All @@ -27,7 +23,7 @@ maven/mavencentral/com.github.fge/jackson-coreutils/1.6, Apache-2.0 or LGPL-3.0-
maven/mavencentral/com.github.fge/jackson-coreutils/1.8, LGPL-3.0 OR Apache-2.0, approved, clearlydefined
maven/mavencentral/com.github.fge/json-patch/1.6, LGPL-3.0 OR Apache-2.0, restricted, clearlydefined
maven/mavencentral/com.github.fge/msg-simple/1.1, Apache-2.0 OR LGPL-3.0-or-later, approved, #2574
maven/mavencentral/com.github.fge/uri-template/0.9, (Apache-2.0 AND LGPL-3.0 AND LGPL-3.0-only) OR (Apache-2.0 AND LGPL-3.0-only), restricted, clearlydefined
maven/mavencentral/com.github.fge/uri-template/0.9, Apache-2.0 OR LGPL-3.0-or-later, approved, #9668
maven/mavencentral/com.github.java-json-tools/btf/1.3, Apache-2.0 OR LGPL-3.0-or-later, approved, #2721
maven/mavencentral/com.github.java-json-tools/jackson-coreutils-equivalence/1.0, LGPL-3.0 OR Apache-2.0, approved, clearlydefined
maven/mavencentral/com.github.java-json-tools/jackson-coreutils/2.0, , approved, #2719
Expand Down Expand Up @@ -58,7 +54,7 @@ maven/mavencentral/com.googlecode.libphonenumber/libphonenumber/8.0.0, Apache-2.
maven/mavencentral/com.googlecode.libphonenumber/libphonenumber/8.11.1, Apache-2.0, approved, clearlydefined
maven/mavencentral/com.puppycrawl.tools/checkstyle/10.0, LGPL-2.1-or-later, approved, #7936
maven/mavencentral/com.rameshkp/openapi-merger-app/1.0.5, , restricted, clearlydefined
maven/mavencentral/com.rameshkp/openapi-merger-gradle-plugin/1.0.5, , restricted, clearlydefined
maven/mavencentral/com.rameshkp/openapi-merger-gradle-plugin/1.0.5, Apache-2.0, approved, #9669
maven/mavencentral/com.squareup.moshi/moshi-adapters/1.14.0, Apache-2.0, approved, clearlydefined
maven/mavencentral/com.squareup.moshi/moshi-kotlin/1.14.0, Apache-2.0, approved, clearlydefined
maven/mavencentral/com.squareup.moshi/moshi/1.14.0, Apache-2.0, approved, clearlydefined
Expand All @@ -73,7 +69,7 @@ maven/mavencentral/commons-io/commons-io/2.6, Apache-2.0, approved, CQ19090
maven/mavencentral/commons-logging/commons-logging/1.2, Apache-2.0, approved, CQ10162
maven/mavencentral/dev.zacsweers.moshix/moshi-sealed-reflect/0.19.0, , restricted, clearlydefined
maven/mavencentral/dev.zacsweers.moshix/moshi-sealed-runtime/0.19.0, , restricted, clearlydefined
maven/mavencentral/gradle.plugin.org.gradle.crypto/checksum/1.4.0, , restricted, clearlydefined
maven/mavencentral/gradle.plugin.org.gradle.crypto/checksum/1.4.0, Apache-2.0, approved, #9667
maven/mavencentral/gradle.plugin.org.hidetake/gradle-swagger-generator-plugin/2.19.2, , restricted, clearlydefined
maven/mavencentral/info.picocli/picocli/4.6.3, Apache-2.0, approved, clearlydefined
maven/mavencentral/io.github.gradle-nexus/publish-plugin/1.3.0, , restricted, clearlydefined
Expand Down Expand Up @@ -109,6 +105,7 @@ maven/mavencentral/net.bytebuddy/byte-buddy/1.14.1, Apache-2.0 AND BSD-3-Clause,
maven/mavencentral/net.sf.jopt-simple/jopt-simple/5.0.3, MIT, approved, CQ13174
maven/mavencentral/net.sf.jopt-simple/jopt-simple/5.0.4, MIT, approved, CQ13174
maven/mavencentral/net.sf.saxon/Saxon-HE/10.6, MPL-2.0 AND W3C, approved, #7945
maven/mavencentral/net.steppschuh.markdowngenerator/markdowngenerator/1.3.1.1, , restricted, clearlydefined
maven/mavencentral/org.antlr/antlr4-runtime/4.9.3, BSD-3-Clause, approved, #322
maven/mavencentral/org.apache.commons/commons-lang3/3.12.0, Apache-2.0, approved, clearlydefined
maven/mavencentral/org.apache.commons/commons-lang3/3.2.1, Apache-2.0, approved, clearlydefined
Expand All @@ -132,7 +129,7 @@ maven/mavencentral/org.jacoco/org.jacoco.core/0.8.8, EPL-2.0, approved, CQ23283
maven/mavencentral/org.jacoco/org.jacoco.report/0.8.8, EPL-2.0 AND Apache-2.0, approved, CQ23284
maven/mavencentral/org.javassist/javassist/3.28.0-GA, Apache-2.0 OR LGPL-2.1-or-later OR MPL-1.1, approved, #327
maven/mavencentral/org.jboss.logging/jboss-logging/3.3.0.Final, Apache-2.0, approved, CQ13772
maven/mavencentral/org.jetbrains.kotlin/kotlin-bom/1.7.22, , restricted, clearlydefined
maven/mavencentral/org.jetbrains.kotlin/kotlin-bom/1.7.22, Apache-2.0, approved, #9665
maven/mavencentral/org.jetbrains.kotlin/kotlin-reflect/1.7.0, Apache-2.0, approved, clearlydefined
maven/mavencentral/org.jetbrains.kotlin/kotlin-reflect/1.7.20, Apache-2.0, approved, clearlydefined
maven/mavencentral/org.jetbrains.kotlin/kotlin-reflect/1.7.22, Apache-2.0, approved, clearlydefined
Expand Down
3 changes: 2 additions & 1 deletion buildSrc/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ dependencies {
implementation(libs.jackson.datatypeJsr310)

api(libs.edc.runtime.metamodel)

implementation(libs.markdown.gen)
}

gradlePlugin {
Expand All @@ -47,6 +47,7 @@ sourceSets {
srcDirs(
"../plugins/autodoc/autodoc-plugin/src/main",
"../plugins/autodoc/autodoc-processor/src/main",
"../plugins/autodoc/autodoc-converters/src/main",
"../plugins/edc-build/src/main",
"../plugins/module-names/src/main",
"../plugins/openapi-merger/src/main",
Expand Down
2 changes: 2 additions & 0 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ plugin-openapi-merger-app = { module = "com.rameshkp:openapi-merger-app", versio
plugin-swagger = { module = "io.swagger.core.v3:swagger-gradle-plugin", version = "2.2.10" }
plugin-swagger-generator = { module = "gradle.plugin.org.hidetake:gradle-swagger-generator-plugin", version = "2.19.2" }

# third party
markdown-gen = { module = "net.steppschuh.markdowngenerator:markdowngenerator", version = "1.3.1.1" }
[bundles]

[plugins]
Expand Down
1 change: 1 addition & 0 deletions plugins/autodoc/autodoc-converters/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This module contains the business logic code for the `autodoc` feature, i.e. the actual annotation processor.
21 changes: 21 additions & 0 deletions plugins/autodoc/autodoc-converters/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
* Copyright (c) 2022 Microsoft Corporation
*
* This program and the accompanying materials are made available under the
* terms of the Apache License, Version 2.0 which is available at
* https://www.apache.org/licenses/LICENSE-2.0
*
* SPDX-License-Identifier: Apache-2.0
*
* Contributors:
* Microsoft Corporation - initial API and implementation
*/

plugins {
`java-library`
}

dependencies {
api(libs.edc.runtime.metamodel)
implementation(libs.markdown.gen)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* Copyright (c) 2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
*
* This program and the accompanying materials are made available under the
* terms of the Apache License, Version 2.0 which is available at
* https://www.apache.org/licenses/LICENSE-2.0
*
* SPDX-License-Identifier: Apache-2.0
*
* Contributors:
* Bayerische Motoren Werke Aktiengesellschaft (BMW AG) - initial API and implementation
*
*/

package org.eclipse.edc.plugins.autodoc.json;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.eclipse.edc.plugins.autodoc.spi.ManifestConverterException;
import org.eclipse.edc.plugins.autodoc.spi.ManifestReader;
import org.eclipse.edc.runtime.metamodel.domain.EdcModule;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.List;

public class JsonManifestReader implements ManifestReader {
private static final TypeReference<List<EdcModule>> MODULE_TYPE_REF = new TypeReference<>() {
};
private final ObjectMapper objectMapper;

public JsonManifestReader(ObjectMapper objectMapper) {
this.objectMapper = objectMapper;
}

@Override
public List<EdcModule> read(InputStream inputStream) {
try {
return objectMapper.readValue(new InputStreamReader(new BufferedInputStream(inputStream)), MODULE_TYPE_REF);
} catch (IOException e) {
throw new ManifestConverterException(e);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
/*
* Copyright (c) 2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
*
* This program and the accompanying materials are made available under the
* terms of the Apache License, Version 2.0 which is available at
* https://www.apache.org/licenses/LICENSE-2.0
*
* SPDX-License-Identifier: Apache-2.0
*
* Contributors:
* Bayerische Motoren Werke Aktiengesellschaft (BMW AG) - initial API and implementation
*
*/

package org.eclipse.edc.plugins.autodoc.markdown;

import net.steppschuh.markdowngenerator.Markdown;
import net.steppschuh.markdowngenerator.MarkdownElement;
import net.steppschuh.markdowngenerator.table.Table;
import org.eclipse.edc.plugins.autodoc.spi.ManifestConverterException;
import org.eclipse.edc.plugins.autodoc.spi.ManifestRenderer;
import org.eclipse.edc.runtime.metamodel.domain.ConfigurationSetting;
import org.eclipse.edc.runtime.metamodel.domain.ModuleType;
import org.eclipse.edc.runtime.metamodel.domain.Service;
import org.eclipse.edc.runtime.metamodel.domain.ServiceReference;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

import static java.lang.String.format;
import static java.util.Optional.ofNullable;
import static net.steppschuh.markdowngenerator.Markdown.bold;
import static net.steppschuh.markdowngenerator.Markdown.code;
import static net.steppschuh.markdowngenerator.Markdown.heading;
import static net.steppschuh.markdowngenerator.Markdown.italic;
import static net.steppschuh.markdowngenerator.Markdown.unorderedList;

public class MarkdownManifestRenderer implements ManifestRenderer {

private static final String NEWLINE = System.lineSeparator();
private final OutputStream output;
private final StringBuilder stringBuilder;

public MarkdownManifestRenderer(OutputStream output) {
this.output = output;
stringBuilder = new StringBuilder();
}

@Override
public void renderDocumentHeader() {
stringBuilder.append(heading(DOCUMENT_HEADING, 1)).append(NEWLINE);
stringBuilder.append(NEWLINE);
}

@Override
public void renderModuleHeading(@Nullable String moduleName, @NotNull String modulePath, @NotNull String version) {
var name = ofNullable(moduleName).orElse(modulePath);

var moduleHeading = heading(format("Module `%s:%s`", name, version), 2);
stringBuilder.append(moduleHeading).append(NEWLINE);

if (moduleName != null) {
stringBuilder.append(italic(modulePath)).append(NEWLINE);
}
stringBuilder.append(NEWLINE);
}

@Override
public void renderCategories(List<String> categories) {
// append categories as italic text
var cat = categories
.stream()
.filter(c -> c != null && !c.isEmpty())
.collect(Collectors.joining(","));

if (cat.isEmpty()) {
cat = NONE;
}

stringBuilder.append(italic(format("Categories: %s", cat))).append(NEWLINE);
stringBuilder.append(NEWLINE);
}

@Override
public void renderExtensionPoints(List<Service> extensionPoints) {
// append extension points
stringBuilder.append(heading(EXTENSION_POINTS, 3)).append(NEWLINE);
stringBuilder.append(listOrNone(unorderedList(extensionPoints.stream().map(s -> code(s.getService())).toList().toArray()))).append(NEWLINE);
stringBuilder.append(NEWLINE);
}

@Override
public void renderExtensionHeading() {
stringBuilder.append(heading(EXTENSIONS, 3)).append(NEWLINE);
}

@Override
public void renderExtensionHeader(@NotNull String className, String name, String overview, ModuleType type) {
stringBuilder.append(heading("Class: " + code(className), 4)).append(NEWLINE);

stringBuilder.append(bold("Name:")).append(format(" \"%s\"", name)).append(NEWLINE);
if (overview != null) {
stringBuilder.append(NEWLINE).append(bold("Overview:")).append(" ").append(overview).append(NEWLINE).append(NEWLINE);
}
stringBuilder.append(NEWLINE);
}

@Override
public void renderConfigurations(List<ConfigurationSetting> configuration) {
// add configuration table
var tableBuilder = new Table.Builder()
.addRow("Key", "Required", "Type", "Pattern", "Min", "Max", "Description");

configuration.forEach(setting -> tableBuilder.addRow(code(setting.getKey()),
setting.isRequired() ? code("*") : null,
code(setting.getType()),
ofNullable(setting.getPattern()).map(Markdown::code).orElse(null),
ofNullable(setting.getMinimum()).map(m -> code(String.valueOf(m))).orElse(null),
ofNullable(setting.getMaximum()).map(m -> code(String.valueOf(m))).orElse(null),
setting.getDescription()));

stringBuilder.append(heading("Configuration: ", 5));
if (!configuration.isEmpty()) {
stringBuilder.append(NEWLINE).append(NEWLINE).append(tableBuilder.build()).append(NEWLINE);
} else {
stringBuilder.append(italic(NONE)).append(NEWLINE);
}
stringBuilder.append(NEWLINE);
}

@Override
public void renderExposedServices(List<Service> provides) {
// add exposed services
stringBuilder.append(heading("Provided services:", 5)).append(NEWLINE);
stringBuilder.append(listOrNone(provides.stream().map(s -> code(s.getService())).toList().toArray())).append(NEWLINE);
stringBuilder.append(NEWLINE);
}

@Override
public void renderReferencedServices(List<ServiceReference> references) {
// add injected services
stringBuilder.append(heading("Referenced (injected) services:", 5)).append(NEWLINE);
stringBuilder.append(listOrNone(references.stream().map(s -> format("%s (%s)", code(s.getService()), s.isRequired() ? "required" : "optional")).toList().toArray())).append(NEWLINE);
stringBuilder.append(NEWLINE);
}

@Override
public OutputStream finalizeRendering() {
try {
output.write(stringBuilder.toString().getBytes(StandardCharsets.UTF_8));
} catch (IOException e) {
throw new ManifestConverterException(e);
}
return output;
}

private MarkdownElement listOrNone(Object... items) {
if (items.length == 0 || Arrays.stream(items).allMatch(o -> o.toString().isEmpty())) {
return italic(NONE);
} else {
return unorderedList(items);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
* Copyright (c) 2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
*
* This program and the accompanying materials are made available under the
* terms of the Apache License, Version 2.0 which is available at
* https://www.apache.org/licenses/LICENSE-2.0
*
* SPDX-License-Identifier: Apache-2.0
*
* Contributors:
* Bayerische Motoren Werke Aktiengesellschaft (BMW AG) - initial API and implementation
*
*/

package org.eclipse.edc.plugins.autodoc.spi;

public class ManifestConverterException extends RuntimeException {
public ManifestConverterException(Throwable e) {
super(e);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* Copyright (c) 2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
*
* This program and the accompanying materials are made available under the
* terms of the Apache License, Version 2.0 which is available at
* https://www.apache.org/licenses/LICENSE-2.0
*
* SPDX-License-Identifier: Apache-2.0
*
* Contributors:
* Bayerische Motoren Werke Aktiengesellschaft (BMW AG) - initial API and implementation
*
*/

package org.eclipse.edc.plugins.autodoc.spi;

import org.eclipse.edc.runtime.metamodel.domain.EdcModule;

import java.io.InputStream;
import java.util.List;

/**
* Reads a manifest file, which contains a {@link List} of {@link EdcModule}. Implementations are file-format specific.
*/
public interface ManifestReader {
/**
* Reads an input stream, e.g. a FileInput stream, and interprets it
*
* @param inputStream The input
*/
List<EdcModule> read(InputStream inputStream);
}
Loading

0 comments on commit fe44324

Please sign in to comment.