Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/scripts/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
<head>
<meta charset="utf-8">
<meta http-equiv="refresh"
content="0;url=https://eclipse-dataspace-protocol-base.github.io/DataspaceProtocol/2025-1-err1"/>
<link rel="canonical" href="https://eclipse-dataspace-protocol-base.github.io/DataspaceProtocol/2025-1-err1"/>
content="0;url=PAGES_REDIRECT_URL"/>
<link rel="canonical" href="PAGES_REDIRECT_URL"/>
</head>
<body>
<h4>
This redirects to the latest Release Candidate <a href="https://eclipse-dataspace-protocol-base.github.io/DataspaceProtocol/2025-1-err1">here</a>
This redirects to the latest Release Candidate <a href="PAGES_REDIRECT_URL">here</a>
</h4>
</body>
</html>
6 changes: 5 additions & 1 deletion .github/workflows/autopublish.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,11 @@ jobs:
chmod +x ./.github/scripts/checkout-tags.sh
./.github/scripts/checkout-tags.sh
- name: Redirect top to head
run: cp .github/scripts/index.html .
run: |
REPO_OWNER="${GITHUB_REPOSITORY%%/*}"
REPO_NAME="${GITHUB_REPOSITORY##*/}"
PAGES_REDIRECT_URL="https://${REPO_OWNER}.github.io/${REPO_NAME}/2025-1-err1"
sed "s|PAGES_REDIRECT_URL|${PAGES_REDIRECT_URL}|g" .github/scripts/index.html > index.html
- uses: actions/upload-pages-artifact@v3
with:
path: .
Expand Down
2 changes: 1 addition & 1 deletion WEBSITE.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ When wanting to pin and publish a snapshot in time via a separate url-path, foll
When the content is finished, a release requires a first commit with

1. a tag with the exact version string (like `2025-1-RC1`) on the release commit
2. to change the redirect in `.github/scripts/index.html` to point to latest release candidate
2. to change the redirect target version in `.github/workflows/autopublish.yaml` (`PAGES_REDIRECT_URL`) to point to the latest release candidate (the URL is constructed dynamically from the repository owner and name)
3. set the `respecConfig.publishDate` in `index.html` to a string like `"2025-02-27"`,`
4. set the `respecConfig.specStatus` in `index.html` to `base`

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ public void apply(@NotNull Project project) {
var schemaModel = parser.parseFiles(stream);

schemaModel.getSchemaTypes().stream()
.filter(type -> !type.isRootDefinition() && !type.isJsonBaseType()) // do not process built-in Json types and root schema types
.filter(type -> !type.isRootDefinition() && !type.isJsonBaseType() && !type.isNamedScalar()) // do not process built-in Json types and root schema types
.forEach(type -> {
var content = htmlTransformer.transform(type);
var destination = new File(tablesDir, type.getName().toLowerCase() + ".html");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,10 @@ private Stream<SchemaType> parseTypes(String schemaPath, Map<String, Object> par
var itemType = parseItemType(definition, baseType);
var context = prefix + schemaPath.substring(resolutionPath.length());
var schemaType = new SchemaType(type, baseType, itemType, context);
var enumValues = (List<Object>) definition.get(ENUM);
if (enumValues != null) {
schemaType.enumValues(enumValues);
}
parseAttributes(definition, schemaType);
return schemaType;
}
Expand Down Expand Up @@ -209,6 +213,12 @@ private void parseReferences(Map<String, Object> definition, ConstraintType cons
.toList();
schemaType.properties(properties);

if (constraintType == ConstraintType.ALL_OF) {
constraintDef.stream()
.filter(e -> e.get(REF) == null)
.forEach(e -> parseRequired(e, schemaType));
}

// parse references
var references = constraintDef
.stream()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,20 +121,22 @@ public void resolve() {
.stream()
.filter(ref -> ref.getResolvedProperty() == null)
.forEach(ref -> {
// check in allOf
// check in allOf (transitively, since properties may be defined in nested allOf entries)
var resolved = type.getResolvedAllOf().stream()
.flatMap(t -> t.getProperties().stream()
.flatMap(t -> t.getTransitiveProperties().stream()
.map(p -> p.getName().equals(ref.getName()) ? p : null)
.filter(Objects::nonNull)).findFirst().orElse(null);

ref.resolvedProperty(resolved);

resolved = type.getResolvedOneOf().stream()
.flatMap(t -> t.getProperties().stream()
.map(p -> p.getName().equals(ref.getName()) ? p : null)
.filter(Objects::nonNull)).findFirst().orElse(null);
if (resolved == null) {
resolved = type.getResolvedOneOf().stream()
.flatMap(t -> t.getTransitiveProperties().stream()
.map(p -> p.getName().equals(ref.getName()) ? p : null)
.filter(Objects::nonNull)).findFirst().orElse(null);
}

ref.resolvedProperty(resolved);
if (resolved != null) {
ref.resolvedProperty(resolved);
}
}));


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ public class SchemaType implements Comparable<SchemaType> {
private final Map<String, SchemaPropertyReference> optionalProperties = new HashMap<>();

private boolean jsonBaseType; // denotes if this type represents a base Json type, e.g. string, object, array
private final Set<Object> enumValues = new TreeSet<>();

/**
* Ctor for base Json types.
Expand Down Expand Up @@ -110,11 +111,31 @@ public String getSchemaUri() {
return schemaUri;
}

public Set<Object> getEnumValues() {
return enumValues;
}

public void enumValues(Collection<Object> values) {
enumValues.addAll(values);
}

public boolean isNamedScalar() {
return !jsonBaseType && properties.isEmpty() && resolvedAllOf.isEmpty() && resolvedOneOf.isEmpty();
}

@NotNull
public Set<SchemaProperty> getProperties() {
return properties;
}

@NotNull
public Set<SchemaProperty> getTransitiveProperties() {
return concat(properties.stream(),
concat(resolvedAllOf.stream().flatMap(t -> t.getTransitiveProperties().stream()),
resolvedOneOf.stream().flatMap(t -> t.getTransitiveProperties().stream())))
.collect(toCollection(TreeSet::new));
}

public Collection<SchemaPropertyReference> getRequiredProperties() {
return requiredProperties.values();
}
Expand All @@ -129,8 +150,8 @@ public Set<SchemaPropertyReference> getTransitiveRequiredProperties() {

@NotNull
public Set<SchemaPropertyReference> getTransitiveOptionalProperties() {
// a type may include multiple other types (allOf) where a property is optional in one but mandatory in another - filter it
var required = getRequiredProperties().stream().map(SchemaPropertyReference::getName).collect(Collectors.toSet());
// a type may include multiple other types (allOf/oneOf) where a property is optional in one but mandatory in another - filter it
var required = getTransitiveRequiredProperties().stream().map(SchemaPropertyReference::getName).collect(Collectors.toSet());
return concat(optionalProperties.values().stream(),
concat(resolvedAllOf.stream().flatMap(type -> type.getTransitiveOptionalProperties().stream()),
resolvedOneOf.stream().flatMap(type -> type.getTransitiveOptionalProperties().stream())))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ public class HtmlTableTransformer implements SchemaTypeTransformer<String> {
public String transform(SchemaType schemaType) {
var builder = new StringBuilder(CSS).append("<table class=\"message-table\">");
builder.append(format("<tr><td class=\"message-class\" colspan=\"4\" id=\"%s-table\">%s</td></tr>", schemaType.getName(), schemaType.getName()));
if (!schemaType.getEnumValues().isEmpty()) {
var values = schemaType.getEnumValues().stream().map(Object::toString).collect(Collectors.joining(", "));
builder.append(format("<tr><td colspan=\"4\"><span class=\"code\">%s</span></td></tr>", values));
}
transformProperties(schemaType.getTransitiveRequiredProperties(), true, builder);
transformProperties(schemaType.getTransitiveOptionalProperties(), false, builder);
return builder.append("</table>").toString();
Expand All @@ -64,7 +68,22 @@ private void transformProperty(SchemaPropertyReference propertyReference, boolea
resolvedTypes = parseResolvedTypes(resolvedProperty);
}
builder.append(format("<td>%s</td>", resolvedTypes));
if (resolvedProperty.getConstantValue() != null) {

// if all resolved types are named scalars, render their base type and enum values
var namedScalars = resolvedProperty.getResolvedTypes().stream()
.filter(this::isNamedScalar)
.toList();
if (!namedScalars.isEmpty() && namedScalars.size() == resolvedProperty.getResolvedTypes().size()) {
var enumValues = namedScalars.stream()
.flatMap(t -> t.getEnumValues().stream())
.map(Object::toString)
.collect(Collectors.joining(", "));
if (!enumValues.isEmpty()) {
builder.append(format("<td>Must be one of:<br><span class=\"code\">%s</span></td>", enumValues));
} else {
builder.append(format("<td>%s</td>", resolvedProperty.getDescription()));
}
} else if (resolvedProperty.getConstantValue() != null) {
builder.append(format("<td>Value must be <span class=\"code\">%s</span></td>", resolvedProperty.getConstantValue()));
} else if (!resolvedProperty.getEnumValues().isEmpty()) {
var values = resolvedProperty.getEnumValues().stream()
Expand All @@ -88,39 +107,36 @@ private void transformProperty(SchemaPropertyReference propertyReference, boolea
builder.append("</tr>");
}

private boolean isNamedScalar(SchemaType schemaType) {
return schemaType.isNamedScalar();
}

private String parseResolvedTypes(SchemaProperty property) {
String resolvedTypes = "";
if (property.getItemTypes().isEmpty()) {
resolvedTypes = property
.getResolvedTypes().stream().map(schemaType -> {
if (schemaType.getItemType() != null) {
return "array[" + schemaType.getItemType() + "]";
}
return getTypeName(schemaType);
}).collect(joining(", "));
if (!property.getItemTypes().isEmpty()) {
return "";
}
return resolvedTypes;
return property.getResolvedTypes().stream()
.map(schemaType -> {
if (schemaType.getItemType() != null) {
return "array[" + schemaType.getItemType() + "]";
}
if (isNamedScalar(schemaType)) {
return schemaType.getBaseType();
}
return typeNameWithLink(schemaType);
})
.collect(joining(", "));
}

private @NotNull String getConstraintOrArrayTypeName(SchemaProperty resolvedProperty) {
var itemTypes = resolvedProperty.getItemTypes().stream()
.flatMap(t -> t.getResolvedTypes().stream())
.map(e -> {
if (e.isJsonBaseType() || getTypeName(e).startsWith("array")) {
return String.format("%s", getTypeName(e));
}
return String.format("<a href=#%s-table>%s</a>", getTypeName(e), getTypeName(e));
})
.map(this::typeNameWithLink)
.collect(joining(", "));
if (itemTypes.isEmpty()) {
itemTypes = resolvedProperty.getResolvedTypes().stream()
.filter(e -> getTypeName(e) != null)
.map(e -> {
if (e.isJsonBaseType()) {
return String.format("%s", getTypeName(e));
}
return String.format("<a href=#%s-table>%s</a>", getTypeName(e), getTypeName(e));
})
.map(this::typeNameWithLink)
.collect(joining(", "));
if (itemTypes.isEmpty()) {
return "array";
Expand All @@ -138,6 +154,14 @@ private String parseResolvedTypes(SchemaProperty property) {
return "array[" + itemTypes + "]";
}

private String typeNameWithLink(SchemaType schemaType) {
var name = getTypeName(schemaType);
if (name == null || schemaType.isJsonBaseType() || name.startsWith("array")) {
return name;
}
return String.format("<a href=#%s-table>%s</a>", name, name);
}

private String getTypeName(SchemaType schemaType) {
if (schemaType.isRootDefinition()) {
// root definition, check to see if it has an allOf, and if not, fallback to the Json base type
Expand Down
Loading