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

knowledgepixels / nanopub-registry / 24139339422

08 Apr 2026 01:58PM UTC coverage: 32.357% (-0.5%) from 32.824%
24139339422

Pull #98

github

web-flow
Merge f359f2357 into 689a63b39
Pull Request #98: Revert seqNum batch allocation, use atomic counter

265 of 916 branches covered (28.93%)

Branch coverage included in aggregate %.

785 of 2329 relevant lines covered (33.71%)

5.66 hits per line

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

92.47
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-Status", serverInfo.get("status") + "");
33✔
44
        context.response().putHeader("Nanopub-Registry-Setup-Id", serverInfo.get("setupId") + "");
33✔
45
        context.response().putHeader("Nanopub-Registry-Trust-State-Counter", serverInfo.get("trustStateCounter") + "");
33✔
46
        context.response().putHeader("Nanopub-Registry-Last-Trust-State-Update", serverInfo.get("lastTrustStateUpdate") + "");
33✔
47
        context.response().putHeader("Nanopub-Registry-Trust-State-Hash", serverInfo.get("trustStateHash") + "");
33✔
48
        Object maxCounter = getMaxValue(mongoSession, Collection.NANOPUBS.toString(), "counter");
18✔
49
        context.response().putHeader("Nanopub-Registry-Load-Counter", maxCounter + "");
24✔
50
        context.response().putHeader("Nanopub-Registry-Nanopub-Count", collection(Collection.NANOPUBS.toString()).estimatedDocumentCount() + "");
30✔
51
        context.response().putHeader("Nanopub-Registry-Test-Instance", String.valueOf(serverInfo.get("testInstance") != null && (Boolean) serverInfo.get("testInstance")));
57!
52
        context.response().putHeader("Nanopub-Registry-Coverage-Types", serverInfo.get("coverageTypes") != null ? serverInfo.get("coverageTypes").toString() : "all");
33!
53
        context.response().putHeader("Nanopub-Registry-Coverage-Agents", serverInfo.get("coverageAgents") != null ? serverInfo.get("coverageAgents").toString() : "viaSetting");
33!
54

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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