Skip to content
Draft
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
57 changes: 57 additions & 0 deletions codegen/templates/java.java.erb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import io.cucumber.messages.Property;
import org.jspecify.annotations.Nullable;

import java.util.List;
import java.util.Map;
import java.util.LinkedHashMap;
import java.util.Objects;
import java.util.Optional;

Expand Down Expand Up @@ -96,6 +98,61 @@ public final class <%= class_name(key) %> {
<%- end -%>
<%- end -%>

Map<String, Object> toJson() {
var json = new LinkedHashMap<String, Object>();

<%- schema['properties'].each do |(property_name, property)|
required = (schema['required'] || []).index(property_name)
-%>
<%- if required -%>
<%- if property['items'] -%>
json.put("<%= property_name %>", <%= property_name %>.stream().map(Json::convert).toList());
<%- else -%>
json.put("<%= property_name %>", Json.convert(<%= property_name %>));
<%- end -%>
<%- else -%>
if(<%= property_name %> != null){
<%- if property['items'] -%>
json.put("<%= property_name %>", <%= property_name %>.stream().map(Json::convert).toList());
<%- else -%>
json.put("<%= property_name %>", Json.convert(<%= property_name %>));
<%- end -%>
}
<%- end -%>
<%- end -%>

return json;
}

//TODO: Rework from fromJson to look like this
// static Rule fromJson(Object json) {
//var map = Json.requireMap(json, "Rule must be a map");
// return new Rule (
// Json.readLocation(map.get("location"), "Rule.location"),
// Json.readArray(map.get("tags"), "Rule.tags", Json::readTag)
// );
}
static <%= class_name(key) %> fromJson(Object json) {
var map = Json.requireMap(json, "<%= class_name(key) %> must be a map");
return new <%= class_name(key) %> (
<%- schema['properties'].each_with_index do |(property_name, property), index| -%>
<%- if property['enum'] -%>
<%= type_for(class_name(key), property_name, property) -%>.fromValue(Json.requireString(map.get("<%= property_name %>"), "<%= class_name(key) %>.<%= property_name %> must be a string"))<%= index < schema['properties'].length-1 ? ',' : '' %>
<%- elsif property['type'] == 'string'-%>
Json.requireString(map.get("<%= property_name %>"), "<%= class_name(key) %>.<%= property_name %> must be a string")<%= index < schema['properties'].length-1 ? ',' : '' %>
<%- elsif property['type'] == 'integer'-%>
Json.to<%= type_for(class_name(key), property_name, property) -%>(map.get("<%= property_name %>"), "<%= class_name(key) %>.<%= property_name %> must be an integer ")<%= index < schema['properties'].length-1 ? ',' : '' %>
<%- elsif property['type'] == 'boolean'-%>
Json.requireBoolean(map.get("<%= property_name %>"), "<%= class_name(key) %>.<%= property_name %> must be a boolean")<%= index < schema['properties'].length-1 ? ',' : '' %>
<%- elsif property['type'] == 'array'-%>
Json.requireArray(map.get("<%= property_name %>"), "<%= class_name(key) %>.<%= property_name %> must be an array").stream().map(<%= type_for(class_name(key), nil, property['items']) %>::fromJson).toList()<%= index < schema['properties'].length-1 ? ',' : '' %>
<%- else -%>
<%= type_for(class_name(key), property_name, property) -%>.fromJson(Json.toObject("<%= class_name(key) %>.<%= property_name %> must be a map", map.get("<%= property_name %>")))<%= index < schema['properties'].length-1 ? ',' : '' %>
<%- end -%>
<%- end -%>
);
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
Expand Down
96 changes: 96 additions & 0 deletions codegen/templates/json.java.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
Json.java
package io.cucumber.messages.types;

import io.cucumber.messages.Property;

import java.util.List;
import java.util.Map;
import java.util.LinkedHashMap;
import java.util.Objects;
import java.util.Optional;

import static java.util.Objects.requireNonNull;

// Generated code
@SuppressWarnings({"unused", "JavaLangClash"})
final class Json {

static Map<String, Object> toObject(String msg, Object o) {
if (o instanceof Map<?, ?> i){
return (Map<String, Object>)i;
}
throw new IllegalArgumentException(msg);
}

static Map<String, Object> requireMap(Object o, String msg) {
if (o instanceof Map<?, ?> i){
return (Map<String, Object>)i;
}
throw new IllegalArgumentException(msg);
}


static String requireString(Object o, String msg) {
if (o instanceof String i){
return i;
}
throw new IllegalArgumentException(msg);
}

static Boolean requireBoolean(Object o, String msg) {
if (o instanceof Boolean i){
return i;
}
throw new IllegalArgumentException(msg);
}

static Long toLong(Object o, String msg) {
if (o instanceof Number i){
return i.longValue();
}
throw new IllegalArgumentException(msg);
}

static Integer toInteger(Object o, String msg) {
if (o instanceof Number i){
return i.intValue();
}
throw new IllegalArgumentException(msg);
}

static List<Object> requireArray(Object o, String msg) {
if (o instanceof List<?> i){
return (List<Object>)i;
}
throw new IllegalArgumentException(msg);
}

static Object convert(String o) {
return o;
}

static Object convert(Long o) {
return o;
}

static Object convert(Integer o) {
return o;
}


static Object convert(Boolean o) {
return o;
}

<% @enums.each do |enum| -%>
static Object convert(<%= enum[:name] %> o) {
return o.value();
}
<% end -%>
<%- @schemas.each do |key, schema| -%>
static Object convert(<%= class_name(key) %> o) {
return o.toJson();
}
<% end -%>

}
1 change: 1 addition & 0 deletions java/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ clean: ## Remove automatically generated files and related artifacts

.generate-messages: $(schemas) ../codegen/codegen.rb ../codegen/templates/java.java.erb ../codegen/templates/java.enum.java.erb
ruby ../codegen/codegen.rb Generator::Java java.java.erb > Generated.java.tmp
ruby ../codegen/codegen.rb Generator::Java json.java.erb >> Generated.java.tmp
ruby ../codegen/codegen.rb Generator::Java java.enum.java.erb >> Generated.java.tmp
csplit --quiet --prefix=Generated --suffix-format=%02d.java.tmp --elide-empty-files Generated.java.tmp /^[A-Za-z.]*[.]java/ {*}
rm Generated.java.tmp
Expand Down
Loading