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

knowledgepixels / nanodash / 17153434891

22 Aug 2025 10:57AM UTC coverage: 12.446% (+0.004%) from 12.442%
17153434891

push

github

tkuhn
Add environment variable for main Nanopub Registry instance

330 of 3766 branches covered (8.76%)

Branch coverage included in aggregate %.

978 of 6743 relevant lines covered (14.5%)

0.64 hits per line

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

31.11
src/main/java/com/knowledgepixels/nanodash/UserData.java
1
package com.knowledgepixels.nanodash;
2

3
import org.apache.commons.exec.environment.EnvironmentUtils;
4
import org.eclipse.rdf4j.common.exception.RDF4JException;
5
import org.eclipse.rdf4j.model.IRI;
6
import org.eclipse.rdf4j.model.ValueFactory;
7
import org.eclipse.rdf4j.model.impl.SimpleValueFactory;
8
import org.nanopub.MalformedNanopubException;
9
import org.nanopub.Nanopub;
10
import org.nanopub.NanopubUtils;
11
import org.nanopub.SimpleTimestampPattern;
12
import org.nanopub.extra.security.MalformedCryptoElementException;
13
import org.nanopub.extra.security.NanopubSignatureElement;
14
import org.nanopub.extra.security.SignatureUtils;
15
import org.nanopub.extra.server.GetNanopub;
16
import org.nanopub.extra.services.ApiResponseEntry;
17
import org.nanopub.extra.setting.IntroNanopub;
18
import org.nanopub.extra.setting.NanopubSetting;
19

20
import java.io.IOException;
21
import java.io.Serializable;
22
import java.util.*;
23

24
/**
25
 * UserData class manages user-related data.
26
 */
27
public class UserData implements Serializable {
28

29
    private static final long serialVersionUID = 1L;
30

31
    private static ValueFactory vf = SimpleValueFactory.getInstance();
3✔
32

33
    private Map<IRI, Set<String>> approvedIdPubkeyhashMap = new HashMap<>();
5✔
34
    private Map<String, Set<IRI>> approvedPubkeyhashIdMap = new HashMap<>();
5✔
35
    private Map<String, Set<IRI>> approvedPubkeyhashLocationMap = new HashMap<>();
5✔
36
    private Map<IRI, Set<String>> unapprovedIdPubkeyhashMap = new HashMap<>();
5✔
37
    private Map<String, Set<IRI>> unapprovedPubkeyhashIdMap = new HashMap<>();
5✔
38
    private Map<String, Set<IRI>> unapprovedPubkeyhashLocationMap = new HashMap<>();
5✔
39
    private Map<String, Set<IRI>> pubkeyhashIntroMap = new HashMap<>();
5✔
40
    private Map<IRI, IntroNanopub> introMap = new HashMap<>();
5✔
41
    private Set<IRI> approvedIntros = new HashSet<>();
5✔
42
    private Map<IRI, String> idNameMap = new HashMap<>();
5✔
43
    private Map<IRI, List<IntroNanopub>> introNanopubLists = new HashMap<>();
5✔
44

45
    /**
46
     * Default constructor for UserData.
47
     * Initializes the user data by fetching nanopublications settings.
48
     */
49
    UserData() {
2✔
50
        final NanodashPreferences pref = NanodashPreferences.get();
2✔
51

52
        // TODO Make nanopublication setting configurable:
53
        NanopubSetting setting;
54
        if (pref.getSettingUri() != null) {
3!
55
            setting = new NanopubSetting(GetNanopub.get(pref.getSettingUri()));
×
56
        } else {
57
            try {
58
                setting = NanopubSetting.getLocalSetting();
2✔
59
            } catch (RDF4JException | MalformedNanopubException | IOException ex) {
×
60
                throw new RuntimeException(ex);
×
61
            }
1✔
62
        }
63
        String settingId = setting.getNanopub().getUri().stringValue();
5✔
64
        if (setting.getUpdateStrategy().stringValue().equals("http://purl.org/nanopub/x/UpdatesByCreator")) {
6!
65
            settingId = QueryApiAccess.getLatestVersionId(settingId);
3✔
66
            setting = new NanopubSetting(GetNanopub.get(settingId));
6✔
67
        }
68
        System.err.println("Using nanopublication setting: " + settingId);
4✔
69

70
//                // Get users that are listed directly in the authority index, and consider them approved:
71
//                ByteArrayOutputStream out = new ByteArrayOutputStream(); // TODO use piped out-in stream here
72
//                new FetchIndex(setting.getAgentIntroCollection().stringValue(), out, RDFFormat.TRIG, false, true, null).run();
73
//                InputStream in = new ByteArrayInputStream(out.toByteArray());
74
//                try {
75
//                        MultiNanopubRdfHandler.process(RDFFormat.TRIG, in, new MultiNanopubRdfHandler.NanopubHandler() {
76
//                                @Override
77
//                                public void handleNanopub(Nanopub np) {
78
//                                        // TODO: Check that latest version talks about same user
79
//                                        register(QueryApiAccess.getLatestVersionId(np.getUri().stringValue()), true);
80
//                                }
81
//                        });
82
//                } catch (RDFParseException | RDFHandlerException | IOException | MalformedNanopubException ex) {
83
//                        ex.printStackTrace();
84
//                }
85
//
86
//                if (setting.getTrustRangeAlgorithm().stringValue().equals("http://purl.org/nanopub/x/TransitiveTrust")) {
87
//                        ApiResponse resp = QueryApiAccess.forcedGet("get-approved-nanopubs");
88
//                        List<ApiResponseEntry> results = new ArrayList<>(resp.getData());
89
//                        while (true) {
90
//                                boolean keepLooping = false;
91
//                                for (ApiResponseEntry entry : new ArrayList<>(results)) {
92
//                                        if (hasValue(approvedPubkeyIdMap, entry.get("pubkey"), Utils.vf.createIRI(entry.get("approver")))) {
93
//                                                register(entry.get("approved_np"), true);
94
//                                                results.remove(entry);
95
//                                                keepLooping = true;
96
//                                        }
97
//                                }
98
//                                if (!keepLooping) break;
99
//                        }
100
//                }
101

102
        System.err.println("Loading approved users...");
3✔
103
        try {
104
            for (RegistryAccountInfo rai : RegistryAccountInfo.fromUrl(Utils.getMainRegistryUrl() + "list.json")) {
12✔
105
                registerApproved(rai);
3✔
106
            }
1✔
107
        } catch (Exception ex) {
×
108
            throw new RuntimeException(ex);
×
109
        }
1✔
110

111
        System.err.println("Loading user details...");
3✔
112
        // Get latest introductions for all users, including unapproved ones:
113
        for (ApiResponseEntry entry : QueryApiAccess.forcedGet("get-all-user-intros").getData()) {
12✔
114
            register(entry);
3✔
115
        }
1✔
116
    }
1✔
117

118
    private IntroNanopub toIntroNanopub(IRI iri) {
119
        if (iri == null) return null;
×
120
        if (introMap.containsKey(iri)) return introMap.get(iri);
×
121
        Nanopub np = Utils.getNanopub(iri.stringValue());
×
122
        if (np == null) return null;
×
123
        IntroNanopub introNp = new IntroNanopub(np);
×
124
        introMap.put(np.getUri(), introNp);
×
125
        return introNp;
×
126
    }
127

128
    private void registerApproved(RegistryAccountInfo rai) {
129
        if (rai.getAgent().equals("$")) return;
6✔
130
        addValue(approvedIdPubkeyhashMap, rai.getAgentIri(), rai.getPubkey());
8✔
131
        addValue(approvedPubkeyhashIdMap, rai.getPubkey(), rai.getAgentIri());
8✔
132
    }
1✔
133

134
    private void register(ApiResponseEntry entry) {
135
        IRI userIri;
136
        try {
137
            userIri = vf.createIRI(entry.get("user"));
6✔
138
        } catch (IllegalArgumentException ex) {
×
139
            return;
×
140
        }
1✔
141
        String pubkeyhash = entry.get("pubkeyHash");
4✔
142
        boolean approved = approvedIdPubkeyhashMap.containsKey(userIri) && approvedIdPubkeyhashMap.get(userIri).contains(pubkeyhash);
17✔
143
        boolean authoritative = "true".equals(entry.get("authoritative"));
6✔
144
        IRI introNpIri = null;
2✔
145
        try {
146
            introNpIri = vf.createIRI(entry.get("intronp"));
6✔
147
        } catch (IllegalArgumentException ex) {
×
148
        }
1✔
149
        IRI keyLocation = null;
2✔
150
        try {
151
            keyLocation = vf.createIRI(entry.get("keyLocation"));
6✔
152
        } catch (IllegalArgumentException ex) {
1✔
153
        }
1✔
154
        if (approved) {
2✔
155
            if (authoritative) {
2✔
156
                if (introNpIri != null) approvedIntros.add(introNpIri);
7!
157
                if (keyLocation != null) addValue(approvedPubkeyhashLocationMap, pubkeyhash, keyLocation);
9✔
158
            }
159
        } else {
160
            addValue(unapprovedIdPubkeyhashMap, userIri, entry.get("pubkeyHash"));
8✔
161
            addValue(unapprovedPubkeyhashIdMap, entry.get("pubkeyHash"), userIri);
8✔
162
            if (keyLocation != null) addValue(unapprovedPubkeyhashLocationMap, pubkeyhash, keyLocation);
8✔
163
        }
164
        if (introNpIri != null) {
2!
165
            addValue(pubkeyhashIntroMap, entry.get("pubkeyHash"), introNpIri);
8✔
166
        }
167
        String name = entry.get("name");
4✔
168
        if (!"".equals(name) && !idNameMap.containsKey(userIri)) {
9✔
169
            idNameMap.put(userIri, name);
6✔
170
        }
171
    }
1✔
172

173
//        private void register(String npId, boolean approved) {
174
//                if (!TrustyUriUtils.isPotentialTrustyUri(npId)) return;
175
//                IntroNanopub introNp = toIntroNanopub(npId);
176
//                if (introNp == null) {
177
//                        //System.err.println("No latest version of introduction found");
178
//                        return;
179
//                }
180
//                if (introNp.getUser() == null) {
181
//                        //System.err.println("No identifier found in introduction");
182
//                        return;
183
//                }
184
//                if (introNp.getKeyDeclarations().isEmpty()) {
185
//                        //System.err.println("No key declarations found in introduction");
186
//                        return;
187
//                }
188
//                if (approved) {
189
//                        approvedIntroMap.put(introNp.getNanopub().getUri(), introNp);
190
//                }
191
//                String userId = introNp.getUser().stringValue();
192
//                IRI userIri = Utils.vf.createIRI(userId);
193
//                if (userId.startsWith("https://orcid.org/")) {
194
//                        // Some simple ORCID ID wellformedness check:
195
//                        if (!userId.matches("https://orcid.org/[0-9]{4}-[0-9]{4}-[0-9]{4}-[0-9]{3}[0-9X]")) return;
196
//                }
197
//                for (KeyDeclaration kd : introNp.getKeyDeclarations()) {
198
//                        String pubkey = kd.getPublicKeyString();
199
//                        IRI keyLocation = kd.getKeyLocation();
200
//                        if (approved) {
201
//                                addValue(approvedIdPubkeyMap, userIri, pubkey);
202
//                                addValue(approvedPubkeyIdMap, pubkey, userIri);
203
//                                if (keyLocation != null) addValue(approvedPubkeyLocationMap, pubkey, keyLocation);
204
//                        } else {
205
//                                if (!hasValue(approvedIdPubkeyMap, userIri, pubkey)) {
206
//                                        addValue(unapprovedIdPubkeyMap, userIri, pubkey);
207
//                                        addValue(unapprovedPubkeyIdMap, pubkey, userIri);
208
//                                        if (keyLocation != null) addValue(unapprovedPubkeyLocationMap, pubkey, keyLocation);
209
//                                }
210
//                                addValue(pubkeyIntroMap, pubkey, introNp.getNanopub().getUri());
211
//                        }
212
//                }
213
//                if (!idNameMap.containsKey(userIri)) {
214
//                        idNameMap.put(userIri, introNp.getName());
215
//                }
216
//        }
217

218
    private void addValue(Map<IRI, Set<String>> map, IRI key, String value) {
219
        Set<String> values = map.get(key);
5✔
220
        if (values == null) {
2✔
221
            values = new HashSet<>();
4✔
222
            map.put(key, values);
5✔
223
        }
224
        values.add(value);
4✔
225
    }
1✔
226

227
    private void addValue(Map<String, Set<IRI>> map, String key, IRI value) {
228
        Set<IRI> values = map.get(key);
5✔
229
        if (values == null) {
2✔
230
            values = new HashSet<>();
4✔
231
            map.put(key, values);
5✔
232
        }
233
        values.add(value);
4✔
234
    }
1✔
235

236
    private boolean hasValue(Map<IRI, Set<String>> map, IRI key, String value) {
237
        Set<String> values = map.get(key);
×
238
        if (values == null) return false;
×
239
        return values.contains(value);
×
240
    }
241

242
//        private static boolean hasValue(Map<String,Set<IRI>> map, String key, IRI value) {
243
//                Set<IRI> values = map.get(key);
244
//                if (values == null) return false;
245
//                return values.contains(value);
246
//        }
247

248
    /**
249
     * Checks if the given IRI is a user identifier.
250
     *
251
     * @param userIri the IRI to check
252
     * @return true if the IRI is a user identifier, false otherwise
253
     */
254
    public boolean isUser(IRI userIri) {
255
        return approvedIdPubkeyhashMap.containsKey(userIri) || unapprovedIdPubkeyhashMap.containsKey(userIri);
×
256
    }
257

258
    /**
259
     * Checks if the given userId is a valid user identifier.
260
     *
261
     * @param userId the user identifier to check, must start with "https://" or "http://"
262
     * @return true if the userId is a valid user identifier, false otherwise
263
     */
264
    public boolean isUser(String userId) {
265
        if (!userId.startsWith("https://") && !userId.startsWith("http://")) return false;
×
266
        try {
267
            IRI userIri = Utils.vf.createIRI(userId);
×
268
            return approvedIdPubkeyhashMap.containsKey(userIri) || unapprovedIdPubkeyhashMap.containsKey(userIri);
×
269
        } catch (IllegalArgumentException ex) {
×
270
            return false;
×
271
        }
272
    }
273

274
    /**
275
     * Checks if the given public key is approved for the specified user.
276
     *
277
     * @param pubkeyhash the public key to check
278
     * @param user       the IRI of the user to check against
279
     * @return true if the key is approved for the user, false otherwise
280
     */
281
    public boolean isApprovedPubkeyhashForUser(String pubkeyhash, IRI user) {
282
        return hasValue(approvedIdPubkeyhashMap, user, pubkeyhash);
×
283
    }
284

285
    private String getShortName(IRI userIri) {
286
        if (userIri == null) return "(unknown)";
×
287
        String n = userIri.stringValue();
×
288
        n = n.replaceFirst("^https://orcid.org/", "");
×
289
        if (n.length() > 40) return n.substring(0, 30) + "...";
×
290
        return n;
×
291
    }
292

293
    /**
294
     * Retrieves the IRI of a user based on their public key.
295
     *
296
     * @param pubkeyHash   the public key of the user
297
     * @param approvedOnly if true, only approved users are considered; if false, unapproved users are also considered
298
     * @return the IRI of the user if found, or null if not found
299
     */
300
    public IRI getUserIriForPubkeyhash(String pubkeyHash, boolean approvedOnly) {
301
        Set<IRI> userIris = approvedPubkeyhashIdMap.get(pubkeyHash);
×
302
        if (userIris != null && userIris.size() == 1) return userIris.iterator().next();
×
303
        if (!approvedOnly) {
×
304
            userIris = unapprovedPubkeyhashIdMap.get(pubkeyHash);
×
305
            if (userIris != null && userIris.size() == 1) return userIris.iterator().next();
×
306
        }
307
        return null;
×
308
    }
309

310
    public IRI getSignatureOwnerIri(Nanopub np) {
311
        try {
312
            if (np != null) {
2!
313
                NanopubSignatureElement se = SignatureUtils.getSignatureElement(np);
3✔
314
                if (se != null) {
2!
315
                    String pubkeyhash = Utils.createSha256HexHash(se.getPublicKeyString());
×
316
                    return getUserIriForPubkeyhash(pubkeyhash, true);
×
317
                }
318
            }
319
        } catch (MalformedCryptoElementException ex) {
×
320
            ex.printStackTrace();
×
321
        }
1✔
322
        return null;
2✔
323
    }
324

325
    /**
326
     * Retrieves the name of a user based on their IRI.
327
     *
328
     * @param userIri the IRI of the user
329
     * @return the name of the user if found, or null if not found
330
     */
331
    public String getName(IRI userIri) {
332
        return idNameMap.get(userIri);
6✔
333
    }
334

335
    /**
336
     * Retrieves the display name of a user based on their IRI.
337
     *
338
     * @param userIri the IRI of the user
339
     * @return the display name of the user, which includes their name and short name
340
     */
341
    public String getDisplayName(IRI userIri) {
342
        String name = getName(userIri);
×
343
        if (name != null && !name.isEmpty()) {
×
344
            return name + " (" + getShortName(userIri) + ")";
×
345
        }
346
        return getShortName(userIri);
×
347
    }
348

349
    /**
350
     * Retrieves a short display name for a user based on their IRI.
351
     *
352
     * @param userIri the IRI of the user
353
     * @return the short display name of the user, which is either their name or their short name
354
     */
355
    public String getShortDisplayName(IRI userIri) {
356
        String name = getName(userIri);
×
357
        if (name != null && !name.isEmpty()) {
×
358
            return name;
×
359
        }
360
        return getShortName(userIri);
×
361
    }
362

363
    /**
364
     * Retrieves a short display name for a user based on their IRI and public key.
365
     *
366
     * @param userIri    the IRI of the user
367
     * @param pubkeyhash the public key of the user
368
     * @return the short display name of the user, which may include a contested identity note if multiple identities are associated with the public key
369
     */
370
    public String getShortDisplayNameForPubkeyhash(IRI userIri, String pubkeyhash) {
371
        Set<IRI> ids = approvedPubkeyhashIdMap.get(pubkeyhash);
×
372
        if (ids == null || ids.isEmpty()) {
×
373
            ids = unapprovedPubkeyhashIdMap.get(pubkeyhash);
×
374
            if (ids == null || ids.isEmpty()) {
×
375
                return getShortName(userIri);
×
376
            } else if (ids.size() == 1) {
×
377
                return getShortDisplayName(ids.iterator().next());
×
378
            } else {
379
                return getShortName(userIri) + " (contested identity)";
×
380
            }
381
        } else if (ids.size() == 1) {
×
382
            return getShortDisplayName(ids.iterator().next());
×
383
        } else {
384
            return "(contested identity)";
×
385
        }
386
    }
387

388
    /**
389
     * Finds a single user ID for a given public key.
390
     *
391
     * @param pubkeyhash the public key to search for
392
     * @return the IRI of the user if exactly one ID is found for the public key, or null if no ID or multiple IDs are found
393
     */
394
    public IRI findSingleIdForPubkeyhash(String pubkeyhash) {
395
        if (approvedPubkeyhashIdMap.containsKey(pubkeyhash) && !approvedPubkeyhashIdMap.get(pubkeyhash).isEmpty()) {
×
396
            if (approvedPubkeyhashIdMap.get(pubkeyhash).size() == 1) {
×
397
                return approvedPubkeyhashIdMap.get(pubkeyhash).iterator().next();
×
398
            } else {
399
                return null;
×
400
            }
401
        }
402
        if (unapprovedPubkeyhashIdMap.containsKey(pubkeyhash) && !unapprovedPubkeyhashIdMap.get(pubkeyhash).isEmpty()) {
×
403
            if (unapprovedPubkeyhashIdMap.get(pubkeyhash).size() == 1) {
×
404
                return unapprovedPubkeyhashIdMap.get(pubkeyhash).iterator().next();
×
405
            } else {
406
                return null;
×
407
            }
408
        }
409
        return null;
×
410
    }
411

412
    private transient Comparator<IRI> comparator = new Comparator<IRI>() {
12✔
413

414
        @Override
415
        public int compare(IRI iri1, IRI iri2) {
416
            return getDisplayName(iri1).toLowerCase().compareTo(getDisplayName(iri2).toLowerCase());
×
417
        }
418

419
    };
420

421
    /**
422
     * Retrieves a list of users, either approved or unapproved.
423
     *
424
     * @param approved if true, retrieves approved users; if false, retrieves unapproved users
425
     * @return a sorted list of user IRIs
426
     */
427
    public List<IRI> getUsers(boolean approved) {
428
        List<IRI> list;
429
        if (approved) {
×
430
            list = new ArrayList<IRI>(approvedIdPubkeyhashMap.keySet());
×
431
        } else {
432
            list = new ArrayList<IRI>();
×
433
            for (IRI u : unapprovedIdPubkeyhashMap.keySet()) {
×
434
                if (!approvedIdPubkeyhashMap.containsKey(u)) list.add(u);
×
435
            }
×
436
        }
437
        // TODO Cache the sorted list to not sort from scratch each time:
438
        list.sort(comparator);
×
439
        return list;
×
440
    }
441

442
    /**
443
     * Retrieves a list of public keys for a given user.
444
     *
445
     * @param user     the IRI of the user whose public keys are to be retrieved
446
     * @param approved if true, retrieves approved public keys; if false, retrieves unapproved public keys
447
     * @return a list of public keys associated with the user, either approved or unapproved
448
     */
449
    public List<String> getPubkeyhashes(IRI user, Boolean approved) {
450
        List<String> pubkeys = new ArrayList<>();
×
451
        if (user != null) {
×
452
            if (approved == null || approved) {
×
453
                if (approvedIdPubkeyhashMap.containsKey(user)) pubkeys.addAll(approvedIdPubkeyhashMap.get(user));
×
454
            }
455
            if (approved == null || !approved) {
×
456
                if (unapprovedIdPubkeyhashMap.containsKey(user)) pubkeys.addAll(unapprovedIdPubkeyhashMap.get(user));
×
457
            }
458
        }
459
        return pubkeys;
×
460
    }
461

462
    /**
463
     * Retrieves a list of introduction nanopublications for a given user.
464
     *
465
     * @param user the IRI of the user whose introduction nanopublications are to be retrieved
466
     * @return a list of introduction nanopublications associated with the user, sorted by creation time
467
     */
468
    public List<IntroNanopub> getIntroNanopubs(IRI user) {
469
        if (introNanopubLists.containsKey(user)) return introNanopubLists.get(user);
×
470

471
        Map<IRI, IntroNanopub> introNps = new HashMap<>();
×
472
        if (approvedIdPubkeyhashMap.containsKey(user)) {
×
473
            for (String pk : approvedIdPubkeyhashMap.get(user)) {
×
474
                getIntroNanopubs(pk, introNps);
×
475
            }
×
476
        }
477
        if (unapprovedIdPubkeyhashMap.containsKey(user)) {
×
478
            for (String pk : unapprovedIdPubkeyhashMap.get(user)) {
×
479
                getIntroNanopubs(pk, introNps);
×
480
            }
×
481
        }
482
        List<IntroNanopub> list = new ArrayList<>(introNps.values());
×
483
        Collections.sort(list, new Comparator<IntroNanopub>() {
×
484
            @Override
485
            public int compare(IntroNanopub i0, IntroNanopub i1) {
486
                Calendar c0 = SimpleTimestampPattern.getCreationTime(i0.getNanopub());
×
487
                Calendar c1 = SimpleTimestampPattern.getCreationTime(i1.getNanopub());
×
488
                if (c0 == null && c1 == null) return 0;
×
489
                if (c0 == null) return 1;
×
490
                if (c1 == null) return -1;
×
491
                return -c0.compareTo(c1);
×
492
            }
493
        });
494
        introNanopubLists.put(user, list);
×
495
        return list;
×
496
    }
497

498
    /**
499
     * Retrieves a map of introduction nanopublications for a given public key.
500
     *
501
     * @param pubkey the public key for which introduction nanopublications are to be retrieved
502
     * @return a map where the keys are IRI identifiers of introduction nanopublications and the values are the corresponding IntroNanopub objects
503
     */
504
    public Map<IRI, IntroNanopub> getIntroNanopubs(String pubkey) {
505
        Map<IRI, IntroNanopub> introNps = new HashMap<>();
×
506
        getIntroNanopubs(pubkey, introNps);
×
507
        return introNps;
×
508
    }
509

510
    private void getIntroNanopubs(String pubkeyhash, Map<IRI, IntroNanopub> introNps) {
511
        if (pubkeyhashIntroMap.containsKey(pubkeyhash)) {
×
512
            for (IRI iri : pubkeyhashIntroMap.get(pubkeyhash)) {
×
513
                IntroNanopub introNp = toIntroNanopub(iri);
×
514
                if (introNp != null) {
×
515
                    introNps.put(iri, introNp);
×
516
                }
517
            }
×
518
        }
519
    }
×
520

521
    /**
522
     * Checks if the given introduction nanopublication is approved.
523
     *
524
     * @param in the introduction nanopublication to check
525
     * @return true if the introduction nanopublication is approved, false otherwise
526
     */
527
    public boolean isApproved(IntroNanopub in) {
528
        return approvedIntros.contains(in.getNanopub().getUri());
×
529
    }
530

531
    /**
532
     * Retrieves the location of a public key.
533
     *
534
     * @param pubkeyhash the public key for which the location is to be retrieved
535
     * @return the IRI of the key location if found, or null if not found or if multiple locations are associated with the key
536
     */
537
    public IRI getKeyLocationForPubkeyhash(String pubkeyhash) {
538
        if (approvedPubkeyhashLocationMap.containsKey(pubkeyhash) && !approvedPubkeyhashLocationMap.get(pubkeyhash).isEmpty()) {
×
539
            if (approvedPubkeyhashLocationMap.get(pubkeyhash).size() == 1)
×
540
                return approvedPubkeyhashLocationMap.get(pubkeyhash).iterator().next();
×
541
            return null;
×
542
        }
543
        if (unapprovedPubkeyhashLocationMap.containsKey(pubkeyhash) && unapprovedPubkeyhashLocationMap.get(pubkeyhash).size() == 1) {
×
544
            return unapprovedPubkeyhashLocationMap.get(pubkeyhash).iterator().next();
×
545
        }
546
        return null;
×
547
    }
548

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