Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
olinux committed Nov 27, 2023
0 parents commit 39b21b2
Show file tree
Hide file tree
Showing 11 changed files with 522 additions and 0 deletions.
49 changes: 49 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# MIT licensed
name: openMINDS_java_build_pipeline

on:
push:
branches:
- pipeline
workflow_dispatch: # This triggers the workflow when a webhook is received


jobs:
build:
runs-on: ubuntu-latest
steps:

- name: Checkout Repository
uses: actions/checkout@v3

- name: Set up Python 3.11
uses: actions/setup-python@v2
with:
python-version: 3.11

- name: Run build
run: |
pip install -r requirements.txt
python build.py
- name: Checkout main branch
uses: actions/checkout@v3
with:
ref: main
path: main
token: ${{ secrets.GITHUB_TOKEN }}

- name: Push to main
run: |
cp -R target/* main
cd main
rm -rf build openMINDS.egg-info
git config --global user.email "[email protected]"
git config --global user.name "openMINDS pipeline"
if [[ $(git add . --dry-run | wc -l) -gt 0 ]]; then
git add .
git commit -m "build triggered by submodule ${{ inputs.repository }} version ${{ inputs.branch }}"
git push -f
else
echo "Nothing to commit"
fi
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
sources/**
target/**
.idea/**
src/**
70 changes: 70 additions & 0 deletions build.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import os.path
import shutil

from jinja2 import Environment, PackageLoader, select_autoescape

from pipeline.translator import JavaBuilder
from pipeline.utils import clone_sources, SchemaLoader

print("***************************************")
print(f"Triggering the generation of Java classes for openMINDS")
print("***************************************")

# Step 1 - clone central repository in main branch to get the latest sources
clone_sources()
schema_loader = SchemaLoader()
if os.path.exists("target"):
shutil.rmtree("target")

ignored_versions = ["v1.0", "v2.0"]
relevant_versions = [v for v in schema_loader.get_schema_versions() if v not in ignored_versions]


def build_central():
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
)
target_file = "target/src/main/java/org/openmetadatainitiative/openminds/OpenMINDS.java"
os.makedirs(os.path.dirname(target_file), exist_ok=True)
with open(target_file, "w") as target_file:
target_file.write(result)

built_versions = []
packages_by_version = {}


for schema_version in relevant_versions:
# Step 2 - find all involved schemas for the current version
schemas_file_paths = schema_loader.find_schemas(schema_version)
type_to_class_name = {}
implemented_interfaces = {}
builders = []
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()))
if builder.version not in built_versions:
built_versions.append(builder.version)
for property, types in builder.additional_interfaces.items():
for t in types:
if t not in implemented_interfaces:
implemented_interfaces[t] = []
implemented_interfaces[t].append(f"{builder.interface_path(property).replace('/', '.')}")
type_to_class_name[builder.type]=builder.canonical_class_name()
builders.append(builder)


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

build_central()
Empty file added generator/__init__.py
Empty file.
88 changes: 88 additions & 0 deletions generator/templates/OpenMINDS.java.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package org.openmetadatainitiative.openminds;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.openmetadatainitiative.openminds.utils.Instance;
import org.openmetadatainitiative.openminds.utils.OpenMINDSContext;
import org.openmetadatainitiative.openminds.utils.ParsingUtils;
import org.openmetadatainitiative.openminds.utils.LocalId;

import java.io.File;
import java.io.IOException;
import java.util.Arrays;
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.
*/
public class OpenMINDS {

private final OpenMINDSContext context;

private OpenMINDS(OpenMINDSContext context){
this.context = context;
}

private static void persist(String targetDirectory, Stream<Instance> instances){
File dir = new File(targetDirectory);
if(!dir.exists()){
dir.mkdirs();
}
instances.forEach(i -> {
File f = new File(targetDirectory+File.separator+i.getLocalId().id()+".jsonld");
try {
ParsingUtils.OBJECT_MAPPER.writerWithDefaultPrettyPrinter().writeValue(f, i);
} catch (IOException e) {
throw new RuntimeException(e);
}
});
}

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

public static OpenMINDS.{{version[0]|upper}}{{version[1:]}} {{version}}(String idPrefix){
return {{version}}(new OpenMINDSContext(idPrefix, true));
}

private static OpenMINDS.{{version[0]|upper}}{{version[1:]}} {{version}}(OpenMINDSContext context) {
return new OpenMINDS(context).new {{version[0]|upper}}{{version[1:]}}();
}



public class {{version[0]|upper}}{{version[1:]}} {

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:]}}();


public class {{package[0]|upper}}{{package[1:]}}{

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

public class {{class[0]}} {

public {{class[1]}}.Builder create(String localId){
final {{class[1]}}.Builder builder = {{class[1]}}.create(new LocalId(localId));
builders.add(builder);
return builder;
}
}
{% endfor %}
}
{% endfor %}

public void persist(String targetDirectory) {
OpenMINDS.persist(targetDirectory, builders.stream().map(Builder::build));
}
}

{% endfor %}

}
18 changes: 18 additions & 0 deletions generator/templates/interface.java.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package {{package_name}};

import org.openmetadatainitiative.openminds.utils.ByTypeDeserializer;
import org.openmetadatainitiative.openminds.utils.Entity;
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.
*/
public interface {{additional_interface}} extends Entity {
Reference<? extends {{additional_interface}}> getReference();

class Deserializer extends ByTypeDeserializer<{{additional_interface}}> {
public Deserializer() {
super({{types|join(', ')}});
}
}
}
78 changes: 78 additions & 0 deletions generator/templates/schema_class.java.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
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.databind.annotation.JsonDeserialize;
import org.openmetadatainitiative.openminds.utils.*;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

{% for import in imports %}import {{import}};
{% endfor %}

import static {{package_name}}.{{ class_name }}.*;
/**
{{java_doc}}
*
* ATTENTION! This is an autogenerated file based on the openMINDS schema - do not apply manual changes since they are going to be overwritten.
*/
@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 }}";

@JsonIgnore
public Reference<{{ class_name }}> getReference() {
return doGetReference();
}

public static Reference<{{ class_name }}> createReference(InstanceId instanceId) {
return new Reference<>(instanceId);
}

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


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 %}

public {{ class_name }} build() {
if ({{ class_name }}.this.id == null) {
{{ class_name }}.this.id = new InstanceId(UUID.randomUUID().toString());
}
if({{ class_name }}.this.types == null || {{ class_name }}.this.types.isEmpty() || !{{ class_name }}.this.types.contains(SEMANTIC_NAME)){
final List<String> oldValues = {{ class_name }}.this.types;
{{ class_name }}.this.types = new ArrayList<>();
{{ class_name }}.this.types.add(SEMANTIC_NAME);
if(oldValues != null){
{{ class_name }}.this.types.addAll(oldValues);
}
}
return {{ class_name }}.this;
}
}

{% 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] %}
/**
* {{property_descriptions[property]}}
*/{% endif %}
{{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();
}
}
Empty file added pipeline/__init__.py
Empty file.
Loading

0 comments on commit 39b21b2

Please sign in to comment.