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

knowledgepixels / nanopub-registry / 24499269750

16 Apr 2026 08:06AM UTC coverage: 31.816% (+0.2%) from 31.57%
24499269750

push

github

web-flow
Merge pull request #109 from knowledgepixels/feature/expose-version

feat: expose registry version in JSON and response headers

280 of 988 branches covered (28.34%)

Branch coverage included in aggregate %.

838 of 2526 relevant lines covered (33.17%)

5.48 hits per line

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

92.55
src/main/java/com/knowledgepixels/registry/Page.java
1
package com.knowledgepixels.registry;
2

3
import com.mongodb.client.ClientSession;
4
import org.bson.Document;
5
import io.vertx.core.http.HttpMethod;
6
import io.vertx.ext.web.RoutingContext;
7
import org.apache.commons.lang.StringEscapeUtils;
8

9
import java.io.IOException;
10
import java.text.DecimalFormat;
11

12
import static com.knowledgepixels.registry.RegistryDB.*;
13

14
public abstract class Page {
15

16
    protected static final DecimalFormat df8 = new DecimalFormat("0.00000000");
15✔
17
    protected static final DecimalFormat df1 = new DecimalFormat("0.0");
18✔
18

19
    private RoutingContext context;
20
    protected ClientSession mongoSession;
21
    protected Document serverInfo;
22

23
    private String presentationFormat;
24
    private String extension;
25
    private String requestString;
26

27
    /**
28
     * Constructor for the Page class.
29
     *
30
     * @param mongoSession The MongoDB client session.
31
     * @param context      The routing context.
32
     */
33
    public Page(ClientSession mongoSession, RoutingContext context) {
6✔
34
        this.mongoSession = mongoSession;
9✔
35
        this.context = context;
9✔
36
        context.response().setChunked(true);
15✔
37

38
        // Fetch all serverInfo key-value pairs in one query instead of separate getValue calls
39
        serverInfo = new Document();
15✔
40
        for (Document d : collection(Collection.SERVER_INFO.toString()).find(mongoSession)) {
42✔
41
            serverInfo.put(d.getString("_id"), d.get("value"));
30✔
42
        }
3✔
43
        context.response().putHeader("Nanopub-Registry-Version", Utils.getVersion());
18✔
44
        context.response().putHeader("Nanopub-Registry-Status", serverInfo.get("status") + "");
33✔
45
        context.response().putHeader("Nanopub-Registry-Setup-Id", serverInfo.get("setupId") + "");
33✔
46
        context.response().putHeader("Nanopub-Registry-Trust-State-Counter", serverInfo.get("trustStateCounter") + "");
33✔
47
        context.response().putHeader("Nanopub-Registry-Last-Trust-State-Update", serverInfo.get("lastTrustStateUpdate") + "");
33✔
48
        context.response().putHeader("Nanopub-Registry-Trust-State-Hash", serverInfo.get("trustStateHash") + "");
33✔
49
        Object maxCounter = getMaxValue(mongoSession, Collection.NANOPUBS.toString(), "counter");
18✔
50
        context.response().putHeader("Nanopub-Registry-Load-Counter", maxCounter + "");
24✔
51
        context.response().putHeader("Nanopub-Registry-Nanopub-Count", collection(Collection.NANOPUBS.toString()).estimatedDocumentCount() + "");
30✔
52
        context.response().putHeader("Nanopub-Registry-Test-Instance", String.valueOf(serverInfo.get("testInstance") != null && (Boolean) serverInfo.get("testInstance")));
57!
53
        context.response().putHeader("Nanopub-Registry-Coverage-Types", serverInfo.get("coverageTypes") != null ? serverInfo.get("coverageTypes").toString() : "all");
33!
54
        context.response().putHeader("Nanopub-Registry-Coverage-Agents", serverInfo.get("coverageAgents") != null ? serverInfo.get("coverageAgents").toString() : "viaSetting");
33!
55

56
        String r = context.request().path().substring(1);
18✔
57
        if (r.endsWith(".txt")) {
12✔
58
            presentationFormat = "text/plain";
9✔
59
            r = r.replaceFirst("\\.txt$", "");
18✔
60
        } else if (r.endsWith(".html")) {
12✔
61
            presentationFormat = "text/html";
9✔
62
            r = r.replaceFirst("\\.html$", "");
15✔
63
//                } else if (r.endsWith(".gz")) {
64
//                        presentationFormat = "application/x-gzip";
65
//                        r = r.replaceFirst("\\.gz$", "");
66
        }
67
        if (r.matches(".*\\.[a-z]{1,10}")) {
12✔
68
            extension = r.replaceFirst("^.*\\.([a-z]{1,10})$", "$1");
18✔
69
            requestString = r.replaceFirst("^(.*)\\.[a-z]{1,10}$", "$1");
21✔
70
        } else {
71
            requestString = r;
9✔
72
        }
73
    }
3✔
74

75
    /**
76
     * Get the routing context.
77
     *
78
     * @return The routing context.
79
     */
80
    public RoutingContext getContext() {
81
        return context;
9✔
82
    }
83

84
    /**
85
     * Print a line to the response.
86
     *
87
     * @param s The string to print.
88
     */
89
    public void println(String s) {
90
        print(s + "\n");
12✔
91
    }
3✔
92

93
    /**
94
     * Print a string to the response.
95
     *
96
     * @param s The string to print.
97
     */
98
    public void print(String s) {
99
        if (context.request().method() == HttpMethod.HEAD) {
18!
100
            return;
×
101
        }
102
        context.response().write(s);
18✔
103
    }
3✔
104

105
    /**
106
     * Set the response content type.
107
     *
108
     * @param contentType The content type.
109
     */
110
    public void setRespContentType(String contentType) {
111
        if (context.request().method() == HttpMethod.HEAD) {
18✔
112
            return;
3✔
113
        }
114
        context.response().putHeader("Content-Type", contentType);
21✔
115
    }
3✔
116

117
    /**
118
     * Show the page.
119
     *
120
     * @throws IOException
121
     */
122
    protected abstract void show() throws IOException;
123

124
    /**
125
     * Print the HTML header.
126
     *
127
     * @param title The title of the page.
128
     */
129
    public void printHtmlHeader(String title) {
130
        println("<!DOCTYPE HTML>");
9✔
131
        println("<html><head>");
9✔
132
        println("<title>" + title + "</title>");
12✔
133
        println("<meta charset=\"utf-8\"/>");
9✔
134
        println("<script type=\"text/javascript\" src=\"/scripts/nanopub.js\"></script>");
9✔
135
        println("<link rel=\"stylesheet\" href=\"/style.css\" type=\"text/css\" media=\"screen\" title=\"Stylesheet\" />");
9✔
136
        println("</head><body>");
9✔
137
    }
3✔
138

139
    /**
140
     * Print the HTML footer.
141
     */
142
    public void printHtmlFooter() {
143
        println("</body></html>");
9✔
144
    }
3✔
145

146
    /**
147
     * Escape HTML special characters in a string.
148
     *
149
     * @param text The text to escape.
150
     * @return The escaped text.
151
     */
152
    public String escapeHtml(String text) {
153
        return StringEscapeUtils.escapeHtml(text);
×
154
    }
155

156
    /**
157
     * Set the canonical link for this page.
158
     *
159
     * @param url The canonical URL.
160
     */
161
    public void setCanonicalLink(String url) {
162
        context.response().putHeader("Link", "<" + url + ">; rel=\"canonical\"");
24✔
163
    }
3✔
164

165
    /**
166
     * Get the presentation format requested, if any.
167
     *
168
     * @return The presentation format.
169
     */
170
    public String getPresentationFormat() {
171
        return presentationFormat;
9✔
172
    }
173

174
    /**
175
     * Get the extension requested, if any.
176
     *
177
     * @return The extension.
178
     */
179
    public String getExtension() {
180
        return extension;
9✔
181
    }
182

183
    /**
184
     * Get the request string with the leading slash and without extension.
185
     *
186
     * @return The request string.
187
     */
188
    public String getRequestString() {
189
        return "/" + requestString;
12✔
190
    }
191

192
    /**
193
     * Get the full request path.
194
     *
195
     * @return The full request path.
196
     */
197
    public String getFullRequest() {
198
        return context.request().path();
15✔
199
    }
200

201
    /**
202
     * Get a parameter from the request.
203
     *
204
     * @param name         The name of the parameter.
205
     * @param defaultValue The default value of the parameter.
206
     * @return The value of the parameter.
207
     */
208
    public String getParam(String name, String defaultValue) {
209
        String value = context.request().getParam(name);
18✔
210
        if (value == null) value = defaultValue;
12✔
211
        return value;
6✔
212
    }
213

214
    /**
215
     * Check whether the request is empty.
216
     *
217
     * @return True if the request is empty, false otherwise.
218
     */
219
    public boolean isEmpty() {
220
        return requestString.isEmpty();
12✔
221
    }
222

223
    /**
224
     * Check whether the request contains an artifact code.
225
     *
226
     * @return True if the request contains an artifact code, false otherwise.
227
     */
228
    public boolean hasArtifactCode() {
229
        return requestString.matches("RA[A-Za-z0-9\\-_]{43}");
15✔
230
    }
231

232
    /**
233
     * Get the artifact code from the request, if present.
234
     *
235
     * @return The artifact code, or null if not present.
236
     */
237
    public String getArtifactCode() {
238
        if (hasArtifactCode()) {
9✔
239
            return requestString;
9✔
240
        }
241
        return null;
6✔
242
    }
243

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