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

Nanopublication / nanopub-java / 17376074091

01 Sep 2025 11:19AM UTC coverage: 45.497% (+0.02%) from 45.474%
17376074091

push

github

ashleycaselli
fix: add APINotReachable and NotEnoughAPIInstances exceptions and relative tests

825 of 2878 branches covered (28.67%)

Branch coverage included in aggregate %.

4606 of 9059 relevant lines covered (50.84%)

2.43 hits per line

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

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

3
import org.eclipse.rdf4j.model.Value;
4
import org.eclipse.rdf4j.model.util.Values;
5
import org.nanopub.MalformedNanopubException;
6
import org.nanopub.Nanopub;
7
import org.nanopub.extra.server.GetNanopub;
8
import org.nanopub.extra.services.*;
9

10
import java.io.IOException;
11
import java.io.InputStream;
12
import java.net.URI;
13
import java.net.URISyntaxException;
14
import java.net.http.HttpClient;
15
import java.net.http.HttpRequest;
16
import java.net.http.HttpResponse;
17
import java.util.HashMap;
18
import java.util.List;
19
import java.util.Map;
20

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

28
    /**
29
     * The query ID for retrieving FDOs by their ID from the nanopub network.
30
     */
31
    public final static String GET_FDO_QUERY_ID = "RAs0HI_KRAds4w_OOEMl-_ed0nZHFWdfePPXsDHf4kQkU/get-fdo-by-id";
32

33
    private RetrieveFdo() {
34
    }  // no instances allowed
35

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

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

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

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

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

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