Skip to content

Commit

Permalink
handle embedded types
Browse files Browse the repository at this point in the history
  • Loading branch information
olinux committed Nov 30, 2023
1 parent bb212d0 commit e1f619d
Show file tree
Hide file tree
Showing 5 changed files with 166 additions and 58 deletions.
19 changes: 13 additions & 6 deletions build.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,16 @@
relevant_versions = [v for v in schema_loader.get_schema_versions() if v not in ignored_versions]


def build_central():
def build_central(embedded_only):
env = Environment(
loader=PackageLoader("generator"),
autoescape=select_autoescape()
)
template = env.get_template("OpenMINDS.java.j2")
result = template.render(
relevant_versions = built_versions,
packages_by_version = packages_by_version
packages_by_version = packages_by_version,
embedded_only = embedded_only
)
target_file = "target/src/main/java/org/openmetadatainitiative/openminds/OpenMINDS.java"
os.makedirs(os.path.dirname(target_file), exist_ok=True)
Expand All @@ -45,13 +46,19 @@ def build_central():
type_to_class_name = {}
implemented_interfaces = {}
builders = []
linked_types = set()
embedded_types = set()


for schema_file_path in schemas_file_paths:
builder = JavaBuilder(schema_file_path, schema_loader.schemas_sources)
if builder.version not in packages_by_version:
packages_by_version[builder.version] = {}
if builder.relative_path_without_extension[0] not in packages_by_version[builder.version]:
packages_by_version[builder.version][builder.relative_path_without_extension[0]] = []
packages_by_version[builder.version][builder.relative_path_without_extension[0]].append((builder.class_name, builder.canonical_class_name()))
packages_by_version[builder.version][builder.relative_path_without_extension[0]].append((builder.class_name, builder.canonical_class_name(), builder.type))
linked_types.update(builder.linked_types)
embedded_types.update(builder.embedded_types)
if builder.version not in built_versions:
built_versions.append(builder.version)
for property, types in builder.additional_interfaces.items():
Expand All @@ -62,9 +69,9 @@ def build_central():
type_to_class_name[builder.type]=builder.canonical_class_name()
builders.append(builder)


embedded_only = embedded_types-linked_types
for builder in builders:
# Step 3 - translate and build each openMINDS schema as JSON-Schema
builder.build(type_to_class_name, implemented_interfaces)
builder.build(type_to_class_name, implemented_interfaces, embedded_types, embedded_only)

build_central()
build_central(embedded_only)
40 changes: 29 additions & 11 deletions generator/templates/OpenMINDS.java.j2
Original file line number Diff line number Diff line change
@@ -1,43 +1,61 @@
package org.openmetadatainitiative.openminds;

import org.openmetadatainitiative.openminds.utils.Instance;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.core.JsonProcessingException;

import org.openmetadatainitiative.openminds.utils.OpenMINDSContext;
import org.openmetadatainitiative.openminds.utils.ParsingUtils;
import org.openmetadatainitiative.openminds.utils.LocalId;
import org.openmetadatainitiative.openminds.utils.ParsingUtils;
import org.openmetadatainitiative.openminds.utils.PostProcessor;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;

/**
* ATTENTION! This is an autogenerated file based on the openMINDS schema - do not apply manual changes since they are going to be overwritten.
*/
@SuppressWarnings("unused")
public class OpenMINDS {

public static class UnknownEntity{}

private OpenMINDS(){}

{% for version in relevant_versions %}public static OpenMINDS.{{version[0]|upper}}{{version[1:]}} {{version}}() {
return new OpenMINDS().new {{version[0]|upper}}{{version[1:]}}();
{% for version in relevant_versions|sort %}public static OpenMINDS.{{version[0]|upper}}{{version[1:]}} {{version}}() {
return new {{version[0]|upper}}{{version[1:]}}();
}

public final class {{version[0]|upper}}{{version[1:]}} {
public static final class {{version[0]|upper}}{{version[1:]}} {
private {{version[0]|upper}}{{version[1:]}}(){}
@JsonTypeInfo(
use = JsonTypeInfo.Id.NAME,
defaultImpl = UnknownEntity.class
)
@JsonSubTypes({
{% for package in packages_by_version[version].keys()|sort %}{% for class in packages_by_version[version][package] | sort %}{%if class[2] not in embedded_only %}@JsonSubTypes.Type(value = {{class[1]}}.class, name = {{class[1]}}.SEMANTIC_NAME),
{% endif %}{% endfor %}{% endfor %}
})
public interface Entity {
}

public <T extends Entity> T load(String payload) throws JsonProcessingException {
return (T) ParsingUtils.OBJECT_MAPPER.readValue(payload, Entity.class);
}

private final List<org.openmetadatainitiative.openminds.utils.Builder<?>> builders = new ArrayList<>();

{% for package in packages_by_version[version].keys() %}public final OpenMINDS.{{version[0]|upper}}{{version[1:]}}.{{package[0]|upper}}{{package[1:]}} {{package}} = new {{package[0]|upper}}{{package[1:]}}();
{% for package in packages_by_version[version].keys()|sort %}public final OpenMINDS.{{version[0]|upper}}{{version[1:]}}.{{package[0]|upper}}{{package[1:]}} {{package}} = new {{package[0]|upper}}{{package[1:]}}();

public final class {{package[0]|upper}}{{package[1:]}}{
private {{package[0]|upper}}{{package[1:]}}(){}
{% for class in packages_by_version[version][package] %}
{% for class in packages_by_version[version][package] | sort %}{%if class[2] not in embedded_only %}
public {{class[1]}}.Builder create{{class[0]}}(String localId){
final {{class[1]}}.Builder builder = {{class[1]}}.create(new LocalId(localId));
builders.add(builder);
return builder;
}
{% endfor %}
{% endif %}{% endfor %}
}
{% endfor %}

Expand Down
17 changes: 16 additions & 1 deletion generator/templates/interface.java.j2
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,27 @@ import org.openmetadatainitiative.openminds.utils.Reference;
/**
* ATTENTION! This is an autogenerated file based on the openMINDS schema - do not apply manual changes since they are going to be overwritten.
*/
@SuppressWarnings("unused")
public interface {{additional_interface}} extends Entity {
Reference<? extends {{additional_interface}}> getReference();

class Deserializer extends ByTypeDeserializer<{{additional_interface}}> {
public Deserializer() {
super({{types|join(', ')}});
super({{types_with_file_ending|join(', ')}});
}
}
{% if embedded %}
static {{additional_interface}}.EmbeddedBuilder createEmbedded(){
return new EmbeddedBuilder();
}

class EmbeddedBuilder {
{% for t in types %}
public {{t}}.EmbeddedBuilder {{simple_type_names[t][0]|lower}}{{simple_type_names[t][1:]}}(){
return {{t}}.createEmbedded();
}
{% endfor %}

}
{% endif %}
}
56 changes: 40 additions & 16 deletions generator/templates/schema_class.java.j2
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ package {{package_name}};
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonInclude;
import org.openmetadatainitiative.openminds.utils.*;
import java.util.function.Function;

import java.util.ArrayList;
import java.util.List;
Expand All @@ -20,8 +22,10 @@ import static {{package_name}}.{{ class_name }}.SEMANTIC_NAME;
*/
@InstanceType(SEMANTIC_NAME)
@JsonIgnoreProperties(ignoreUnknown = true)
public class {{ class_name }} extends Instance {% if implemented_interfaces %}implements {{ implemented_interfaces|join(', ') }}{% endif %}{
static final String SEMANTIC_NAME = "{{ type }}";
@JsonInclude(JsonInclude.Include.NON_NULL)
@SuppressWarnings("unused")
public class {{ class_name }} extends Instance implements org.openmetadatainitiative.openminds.OpenMINDS.{{version[0]|upper}}{{version[1:]}}.Entity{% if implemented_interfaces %}, {{ implemented_interfaces|join(', ') }}{% endif %}{
public static final String SEMANTIC_NAME = "{{ type }}";

@JsonIgnore
public Reference<{{ class_name }}> getReference() {
Expand All @@ -32,25 +36,51 @@ public class {{ class_name }} extends Instance {% if implemented_interfaces %}im
return new Reference<>(new InstanceId(instanceId));
}

/** For deserialization **/
private {{ class_name }}() {
this(null);
}

private {{ class_name }}(LocalId localId ) {
super(localId);
super(localId, SEMANTIC_NAME);
}

{% if type in embedded_types %}
public class EmbeddedBuilder {

{% for property in properties %}public EmbeddedBuilder {{ builder_for_properties[property] }}
{% endfor %}

public {{ class_name }} build(){
return {{ class_name }}.this;
}
}

public static {{ class_name }}.EmbeddedBuilder createEmbedded(){
return new {{ class_name }}(null).new EmbeddedBuilder();
}
{% endif %}

{%if type not in embedded_types or type not in embedded_only %}
public class Builder implements org.openmetadatainitiative.openminds.utils.Builder<{{ class_name }}>{
{% for property in properties %}{% for line in builder_for_properties[property] %}
{{ line }}
{% endfor %}{% endfor %}
{% for property in properties %}public Builder {{ builder_for_properties[property] }}
{% endfor %}

public {{ class_name }} build(OpenMINDSContext context) {
if ({{ class_name }}.this.id == null) {
{{ class_name }}.this.id = InstanceId.withPrefix(UUID.randomUUID().toString(), context.idPrefix());
}
{{ class_name }}.this.atType = SEMANTIC_NAME;
{{ class_name }}.super.build(context);
return {{ class_name }}.this;
}
}

public static {{ class_name }}.Builder create(LocalId localId){
return new {{ class_name }}(localId).new Builder();
}

public {{ class_name }}.Builder copy(){
return ParsingUtils.OBJECT_MAPPER.convertValue(this, {{ class_name }}.class).new Builder();
}
{% endif %}

{% for property in properties %} @JsonProperty(value = "{%if property in absolute_property_translations%}{{absolute_property_translations[property]}}{%else%}{{property}}{%endif%}")
{{member_for_properties[property]}}
{%if property in property_descriptions and property_descriptions[property] %}
Expand All @@ -60,11 +90,5 @@ public class {{ class_name }} extends Instance {% if implemented_interfaces %}im
{{getter_for_properties[property]}}

{% endfor %}
public static {{ class_name }}.Builder create(LocalId localId){
return new {{ class_name }}(localId).new Builder();
}

public {{ class_name }}.Builder copy(){
return ParsingUtils.OBJECT_MAPPER.convertValue(this, {{ class_name }}.class).new Builder();
}
}
Loading

0 comments on commit e1f619d

Please sign in to comment.