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

Nanopublication / nanopub-java / 17852246692

19 Sep 2025 07:56AM UTC coverage: 51.799% (+0.9%) from 50.885%
17852246692

push

github

tkuhn
feat: Add QueryRef and use multimap

- Simplifies usage of query references
- Allows for multi-values per key for new queries with multi-placeholder

996 of 2882 branches covered (34.56%)

Branch coverage included in aggregate %.

5166 of 9014 relevant lines covered (57.31%)

2.69 hits per line

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

86.11
src/main/java/org/nanopub/fdo/RetrieveFdo.java
1
package org.nanopub.fdo;
2

3
import java.io.IOException;
4
import java.io.InputStream;
5
import java.net.URI;
6
import java.net.URISyntaxException;
7
import java.net.http.HttpClient;
8
import java.net.http.HttpRequest;
9
import java.net.http.HttpResponse;
10
import java.util.List;
11

12
import org.eclipse.rdf4j.model.Value;
13
import org.eclipse.rdf4j.model.util.Values;
14
import org.nanopub.MalformedNanopubException;
15
import org.nanopub.Nanopub;
16
import org.nanopub.NanopubAlreadyFinalizedException;
17
import org.nanopub.extra.server.GetNanopub;
18
import org.nanopub.extra.services.APINotReachableException;
19
import org.nanopub.extra.services.ApiResponse;
20
import org.nanopub.extra.services.ApiResponseEntry;
21
import org.nanopub.extra.services.FailedApiCallException;
22
import org.nanopub.extra.services.NotEnoughAPIInstancesException;
23
import org.nanopub.extra.services.QueryAccess;
24
import org.nanopub.extra.services.QueryRef;
25

26
/**
27
 * Retrieve FDOs (FDO Records) from the nanopub network or handle system.
28
 */
29
// TODO class that provides the Op.Retrieve operations.
30
//      See https://fdo-connect.gitlab.io/ap1/architecture-documentation/main/operation-specification/
31
public class RetrieveFdo {
32

33
    /**
34
     * The query ID for retrieving FDOs by their ID from the nanopub network.
35
     */
36
    public final static String GET_FDO_QUERY_ID = "RAs0HI_KRAds4w_OOEMl-_ed0nZHFWdfePPXsDHf4kQkU/get-fdo-by-id";
37

38
    private RetrieveFdo() {
39
    }  // no instances allowed
40

41
    /**
42
     * Retrieve the NP/FdoRecord from the nanopub network or handle system, always check the nanopub network first.
43
     *
44
     * @param iriOrHandle the IRI or handle of the FDO to resolve
45
     * @return the FdoRecord corresponding to the IRI or handle
46
     * @throws org.nanopub.fdo.FdoNotFoundException if the FDO is not found in either the nanopub network or handle system
47
     */
48
    public static FdoRecord resolveId(String iriOrHandle) throws FdoNotFoundException {
49
        try {
50
            Nanopub np = resolveInNanopubNetwork(iriOrHandle);
3✔
51
            if (np != null) {
2✔
52
                return new FdoRecord(np);
5✔
53
            }
54
            if (FdoUtils.looksLikeHandle(iriOrHandle)) {
3✔
55
                return resolveInHandleSystem(iriOrHandle);
3✔
56
            } else if (FdoUtils.isHandleIri(Values.iri(iriOrHandle))) {
4!
57
                return resolveInHandleSystem(FdoUtils.extractHandle(Values.iri(iriOrHandle)));
5✔
58
            }
59
        } catch (Exception e) {
1✔
60
            throw new FdoNotFoundException(e);
5✔
61
        }
×
62
        throw new FdoNotFoundException("Could not find fdo: " + iriOrHandle);
×
63
    }
64

65
    /**
66
     * Retrieve the newest corresponding Nanopub from the Nanopub network.
67
     *
68
     * @param iriOrHandle the IRI or handle of the FDO to resolve
69
     * @return the Nanopub corresponding to the IRI or handle, or null if not found
70
     * @throws org.nanopub.extra.services.FailedApiCallException if the API call fails
71
     */
72
    public static Nanopub resolveInNanopubNetwork(String iriOrHandle) throws FailedApiCallException, APINotReachableException, NotEnoughAPIInstancesException {
73
        ApiResponse apiResponse = QueryAccess.get(new QueryRef(GET_FDO_QUERY_ID, "fdoid", iriOrHandle));
8✔
74
        List<ApiResponseEntry> data = apiResponse.getData();
3✔
75
        if (data.isEmpty()) {
3✔
76
            return null;
2✔
77
        }
78
        String npRef = data.getFirst().get("np");
6✔
79
        return GetNanopub.get(npRef);
3✔
80
    }
81

82
    /**
83
     * Retrieve the data from the handle system.
84
     *
85
     * @param handle the handle of the FDO to resolve
86
     * @return the FdoRecord corresponding to the handle
87
     * @throws org.nanopub.MalformedNanopubException if the nanopub is malformed
88
     * @throws java.net.URISyntaxException           if the URI is malformed
89
     * @throws java.io.IOException                   if an I/O error occurs
90
     * @throws java.lang.InterruptedException        if the operation is interrupted
91
     */
92
    public static FdoRecord resolveInHandleSystem(String handle) throws MalformedNanopubException, URISyntaxException, IOException, InterruptedException, NanopubAlreadyFinalizedException {
93
        Nanopub np = FdoNanopubCreator.createFromHandleSystem(handle);
3✔
94
        return new FdoRecord(np);
5✔
95
    }
96

97
    /**
98
     * Retrieve the NP/FdoRecord Content (DataRef) from the nanopub network or handle system, always check the nanopub network first.
99
     *
100
     * @param iriOrHandle the IRI or handle of the FDO to resolve
101
     * @return an InputStream containing the content of the FDO
102
     * @throws java.net.URISyntaxException          if the URI is malformed
103
     * @throws java.io.IOException                  if an I/O error occurs
104
     * @throws java.lang.InterruptedException       if the operation is interrupted
105
     * @throws org.nanopub.fdo.FdoNotFoundException if the FDO is not found
106
     */
107
    public static InputStream retrieveContentFromId(String iriOrHandle) throws URISyntaxException, IOException, InterruptedException, FdoNotFoundException {
108
        FdoRecord fdo = resolveId(iriOrHandle);
3✔
109

110
        Value contentUrl = fdo.getDataRef();
3✔
111
        if (contentUrl == null) {
2!
112
            throw new FdoNotFoundException("FDO has no file / DataRef.");
×
113
        }
114
        HttpRequest req = HttpRequest.newBuilder().GET().uri(new URI(contentUrl.stringValue())).build();
10✔
115
        HttpResponse<InputStream> httpResponse = HttpClient.newHttpClient().send(req, responseInfo -> HttpResponse.BodySubscribers.ofInputStream());
5✔
116
        return httpResponse.body();
4✔
117
    }
118

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