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

Nanopublication / nanopub-java / 17069388833

19 Aug 2025 12:21PM UTC coverage: 45.825% (-1.9%) from 47.675%
17069388833

push

github

Ziroli Plutschow
Fixed some TODOs

825 of 2880 branches covered (28.65%)

Branch coverage included in aggregate %.

4603 of 8965 relevant lines covered (51.34%)

2.46 hits per line

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

5.97
src/main/java/org/nanopub/extra/services/QueryAccess.java
1
package org.nanopub.extra.services;
2

3
import com.opencsv.CSVReader;
4
import com.opencsv.CSVWriterBuilder;
5
import com.opencsv.ICSVWriter;
6
import com.opencsv.exceptions.CsvValidationException;
7
import org.apache.commons.lang3.tuple.Pair;
8
import org.apache.http.HttpResponse;
9

10
import java.io.BufferedReader;
11
import java.io.IOException;
12
import java.io.InputStreamReader;
13
import java.io.Writer;
14
import java.util.ArrayList;
15
import java.util.HashMap;
16
import java.util.List;
17
import java.util.Map;
18

19
/**
20
 * Second-generation query API access
21
 */
22
public abstract class QueryAccess {
3✔
23

24
    /**
25
     * Process the header.
26
     *
27
     * @param line the header line from the CSV response
28
     */
29
    protected abstract void processHeader(String[] line);
30

31
    /**
32
     * Process a line of data from the CSV response.
33
     *
34
     * @param line the line of data from the CSV response
35
     */
36
    protected abstract void processLine(String[] line);
37

38
    /**
39
     * Call a query with the given queryId and parameters.
40
     *
41
     * @param queryId the ID of the query to call
42
     * @param params  the parameters to pass to the query
43
     * @throws org.nanopub.extra.services.FailedApiCallException if the API call fails
44
     */
45
    public void call(String queryId, Map<String, String> params) throws FailedApiCallException {
46
        HttpResponse resp = QueryCall.run(queryId, params);
×
47
        try (CSVReader csvReader = new CSVReader(new BufferedReader(new InputStreamReader(resp.getEntity().getContent())))) {
×
48
            String[] line = null;
×
49
            int n = 0;
×
50
            while ((line = csvReader.readNext()) != null) {
×
51
                n++;
×
52
                if (n == 1) {
×
53
                    processHeader(line);
×
54
                } else {
55
                    processLine(line);
×
56
                }
57
            }
58
        } catch (IOException | CsvValidationException ex) {
×
59
            throw new FailedApiCallException(ex);
×
60
        }
×
61
    }
×
62

63
    /**
64
     * Print the response of a query in CSV format to the given writer.
65
     *
66
     * @param queryId the ID of the query to call
67
     * @param params  the parameters to pass to the query
68
     * @param writer  the writer to print the CSV response to
69
     * @throws org.nanopub.extra.services.FailedApiCallException if the API call fails
70
     */
71
    public static void printCvsResponse(String queryId, Map<String, String> params, Writer writer) throws FailedApiCallException {
72
        ICSVWriter icsvWriter = new CSVWriterBuilder(writer).withSeparator(',').build();
×
73
        QueryAccess a = new QueryAccess() {
×
74

75
            @Override
76
            protected void processHeader(String[] line) {
77
                icsvWriter.writeNext(line);
×
78
            }
×
79

80
            @Override
81
            protected void processLine(String[] line) {
82
                icsvWriter.writeNext(line);
×
83
            }
×
84

85
        };
86
        a.call(queryId, params);
×
87
        icsvWriter.flushQuietly();
×
88
    }
×
89

90
    /**
91
     * Get the response of a query as an ApiResponse object.
92
     *
93
     * @param queryId the ID of the query to call
94
     * @param params  the parameters to pass to the query
95
     * @return an ApiResponse object containing the response data
96
     * @throws org.nanopub.extra.services.FailedApiCallException if the API call fails
97
     */
98
    public static ApiResponse get(String queryId, Map<String, String> params) throws FailedApiCallException {
99
        final ApiResponse response = new ApiResponse();
4✔
100
        QueryAccess a = new QueryAccess() {
11✔
101

102
            @Override
103
            protected void processHeader(String[] line) {
104
                response.setHeader(line);
×
105
            }
×
106

107
            @Override
108
            protected void processLine(String[] line) {
109
                response.add(line);
×
110
            }
×
111

112
        };
113
        a.call(queryId, params);
×
114
        return response;
×
115
    }
116

117
    private static Map<String, Pair<Long, String>> latestVersionMap = new HashMap<>();
5✔
118
    // TODO Make a better query for this, where superseded and rejected are excluded from the start:
119
    private static final String GET_NEWER_VERSIONS = "RA3qSfVzcnAeMOODdpgCg4e-bX6KjZYZ2JQXDsSwluMaI/get-newer-versions-of-np";
120

121
    /**
122
     * Get the latest version ID of a nanopublication.
123
     * If the latest version is not cached or is older than 1 hour, it will re-fetch it.
124
     *
125
     * @param nanopubId the ID of the nanopublication
126
     * @return the latest version ID of the nanopublication
127
     */
128
    // TODO Is this method used anywhere, Nanodash has a copy of this.
129
    public static String getLatestVersionId(String nanopubId) {
130
        long currentTime = System.currentTimeMillis();
×
131
        if (!latestVersionMap.containsKey(nanopubId) || currentTime - latestVersionMap.get(nanopubId).getLeft() > 1000 * 60 * 60) {
×
132
            // Re-fetch if existing value is older than 1 hour
133
            Map<String, String> params = new HashMap<>();
×
134
            params.put("np", nanopubId);
×
135
            try {
136
                ApiResponse r = QueryAccess.get(GET_NEWER_VERSIONS, params);
×
137
                List<String> latestList = new ArrayList<>();
×
138
                for (ApiResponseEntry e : r.getData()) {
×
139
                    if (e.get("retractedBy").isEmpty() && e.get("supersededBy").isEmpty()) {
×
140
                        latestList.add(e.get("newerVersion"));
×
141
                    }
142
                }
×
143
                if (latestList.size() == 1) {
×
144
                    String latest = latestList.getFirst();
×
145
                    latestVersionMap.put(nanopubId, Pair.of(currentTime, latest));
×
146
                    return latest;
×
147
                } else {
148
                    return nanopubId;
×
149
                }
150
            } catch (Exception ex) {
×
151
                ex.printStackTrace();
×
152
                return nanopubId;
×
153
            }
154
        }
155
        return latestVersionMap.get(nanopubId).getRight();
×
156
    }
157

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