• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

kit-data-manager / ro-crate-java / #572

10 Nov 2025 11:30AM UTC coverage: 90.126% (-0.7%) from 90.804%
#572

Pull #279

github

web-flow
fix: only add entity types which are not null AND not empty

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Pull Request #279: Next Version (2.1.0-rc4)

231 of 248 new or added lines in 8 files covered. (93.15%)

31 existing lines in 2 files now uncovered.

2209 of 2451 relevant lines covered (90.13%)

0.9 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

40.0
/src/main/java/edu/kit/datamanager/ro_crate/externalproviders/dataentities/ImportFromZenodo.java
1
package edu.kit.datamanager.ro_crate.externalproviders.dataentities;
2

3
import com.apicatalog.jsonld.JsonLd;
4
import com.apicatalog.jsonld.JsonLdError;
5
import com.apicatalog.jsonld.document.JsonDocument;
6
import com.fasterxml.jackson.databind.ObjectMapper;
7
import com.fasterxml.jackson.databind.node.ObjectNode;
8

9
import edu.kit.datamanager.ro_crate.Crate;
10
import edu.kit.datamanager.ro_crate.RoCrate;
11
import edu.kit.datamanager.ro_crate.RoCrate.RoCrateBuilder;
12
import edu.kit.datamanager.ro_crate.entities.contextual.ContextualEntity;
13
import edu.kit.datamanager.ro_crate.entities.data.DataEntity;
14
import edu.kit.datamanager.ro_crate.objectmapper.MyObjectMapper;
15

16
import java.io.ByteArrayInputStream;
17
import java.io.IOException;
18
import java.nio.charset.StandardCharsets;
19
import java.util.Optional;
20

21
import org.apache.http.HttpHeaders;
22
import org.apache.http.client.methods.CloseableHttpResponse;
23
import org.apache.http.client.methods.HttpGet;
24
import org.apache.http.impl.client.CloseableHttpClient;
25
import org.apache.http.impl.client.HttpClients;
26

27
/**
28
 * Class providing functionality for importing a resource from zenodo.
29
 */
30
public class ImportFromZenodo {
31

32
  /**
33
   * Class has only static methods, therefore forbid instance creation.
34
   */
35
  private ImportFromZenodo() {}
36

37
  /**
38
   * Creating a crate and adding the zenodo resource to it.
39
   *
40
   * @param url           the url of the zenodo resource.
41
   * @param name          the name of the crate created.
42
   * @param description   the description of the crate created.
43
   * @param datePublished the published date of the crate.
44
   * @param licenseId     the license identifier of the crate.
45
   * @return the created crate.
46
   */
47
  public static Crate createCrateWithItem(
48
      String url,
49
      Optional<String> name,
50
      Optional<String> description,
51
      Optional<String> datePublished,
52
      Optional<String> licenseId) {
53

54
    RoCrateBuilder builder = new RoCrate.RoCrateBuilder();
1✔
55
    name.ifPresent(builder::addName);
1✔
56
    description.ifPresent(builder::addDescription);
1✔
57
    datePublished.ifPresent(builder::addDatePublishedWithExceptions);
1✔
58
    licenseId.ifPresent(builder::setLicense);
1✔
59

60
    Crate crate = builder.build();
1✔
61
    addToCrateFromZotero(url, crate);
1✔
62
    return crate;
1✔
63
  }
64

65
  public static void addZenodoToCrate(String ulr, Crate crate) {
66
    addToCrateFromZotero(ulr, crate);
1✔
67
  }
1✔
68

69
  private static void addToCrateFromZotero(String url, Crate crate) {
70
    ObjectMapper objectMapper = MyObjectMapper.getMapper();
1✔
71
    CloseableHttpClient httpClient = HttpClients.createDefault();
1✔
72
    HttpGet requestZenodo = new HttpGet(url);
1✔
73

74
    // HttpGet requestSchema= new HttpGet("https://www.researchobject.org/ro-crate/1.1/context.jsonld");
75
    HttpGet requestSchema = new HttpGet("https://schema.org/docs/jsonldcontext.json");
1✔
76
    requestZenodo.addHeader(HttpHeaders.ACCEPT, "application/ld+json");
1✔
77
    ObjectNode jsonNode;
78
    String mainId;
79
    try {
80
      CloseableHttpResponse response = httpClient.execute(requestZenodo);
1✔
81
      var stream = response.getEntity().getContent();
1✔
82

83
      // get the item of the main entity
UNCOV
84
      jsonNode = (ObjectNode) objectMapper.readTree(stream);
×
UNCOV
85
      mainId = jsonNode.get("@id").asText();
×
86

UNCOV
87
      final var el = JsonLd.flatten(JsonDocument.of(
×
88
              new ByteArrayInputStream(
UNCOV
89
                  jsonNode.toString().getBytes(StandardCharsets.UTF_8)))).get();
×
90

UNCOV
91
      CloseableHttpResponse schema = httpClient.execute(requestSchema);
×
UNCOV
92
      ObjectNode doc = (ObjectNode) objectMapper.readTree(schema.getEntity().getContent());
×
UNCOV
93
      var con = (ObjectNode) doc.get("@context");
×
UNCOV
94
      con.remove("type");
×
UNCOV
95
      con.remove("id");
×
UNCOV
96
      doc.set("@context", con);
×
UNCOV
97
      var finalVersion = JsonLd.compact(
×
UNCOV
98
          JsonDocument.of(el),
×
UNCOV
99
          JsonDocument.of(new ByteArrayInputStream(
×
UNCOV
100
              doc.toString().getBytes(StandardCharsets.UTF_8)))).get();
×
101

102

UNCOV
103
      jsonNode = (ObjectNode) objectMapper.readTree(finalVersion.toString());
×
104
    } catch (IOException | JsonLdError e) {
1✔
105
      e.printStackTrace();
1✔
106
      return;
1✔
UNCOV
107
    }
×
108
    // we don't need this context since we are going to add it to a crate which allready has one
UNCOV
109
    jsonNode.remove("@context");
×
UNCOV
110
    var graph = jsonNode.get("@graph");
×
UNCOV
111
    if (graph != null) {
×
UNCOV
112
      for (var entity : graph) {
×
UNCOV
113
        if (entity.get("@id").asText().equals(mainId)) {
×
UNCOV
114
          var dataEntity = new DataEntity.DataEntityBuilder()
×
UNCOV
115
              .setAllUnsafe((ObjectNode) entity).build();
×
UNCOV
116
          crate.addDataEntity(dataEntity);
×
UNCOV
117
        } else {
×
118
          // here we have to think of a way to differentiate between data and contextual entities.
UNCOV
119
          var contextualEntity = new ContextualEntity.ContextualEntityBuilder()
×
UNCOV
120
              .setAllUnsafe((ObjectNode) entity).build();
×
UNCOV
121
          crate.addContextualEntity(contextualEntity);
×
122
        }
UNCOV
123
      }
×
124
    }
UNCOV
125
  }
×
126
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc