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

knowledgepixels / nanodash / 19292766293

12 Nov 2025 09:32AM UTC coverage: 13.802% (-0.4%) from 14.211%
19292766293

push

github

tkuhn
feat(ResourceView): Support for hasActionTemplateQueryMapping

512 of 4746 branches covered (10.79%)

Branch coverage included in aggregate %.

1350 of 8745 relevant lines covered (15.44%)

0.69 hits per line

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

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

3
import org.eclipse.rdf4j.common.exception.RDF4JException;
4
import org.eclipse.rdf4j.model.IRI;
5
import org.eclipse.rdf4j.model.ValueFactory;
6
import org.eclipse.rdf4j.model.impl.SimpleValueFactory;
7
import org.nanopub.MalformedNanopubException;
8
import org.nanopub.Nanopub;
9
import org.nanopub.SimpleTimestampPattern;
10
import org.nanopub.extra.security.MalformedCryptoElementException;
11
import org.nanopub.extra.security.NanopubSignatureElement;
12
import org.nanopub.extra.security.SignatureUtils;
13
import org.nanopub.extra.server.GetNanopub;
14
import org.nanopub.extra.services.ApiResponseEntry;
15
import org.nanopub.extra.services.QueryRef;
16
import org.nanopub.extra.setting.IntroNanopub;
17
import org.nanopub.extra.setting.NanopubSetting;
18
import org.nanopub.vocabulary.NPX;
19
import org.slf4j.Logger;
20
import org.slf4j.LoggerFactory;
21

22
import java.io.IOException;
23
import java.io.Serializable;
24
import java.util.*;
25

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

31
    private static ValueFactory vf = SimpleValueFactory.getInstance();
2✔
32
    private static final Logger logger = LoggerFactory.getLogger(UserData.class);
4✔
33

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

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

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

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

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

112
        logger.info("Loading user details...");
3✔
113
        // Get latest introductions for all users, including unapproved ones:
114
        for (ApiResponseEntry entry : QueryApiAccess.forcedGet(new QueryRef("get-all-user-intros")).getData()) {
11!
115
            register(entry);
×
116
        }
×
117
    }
1✔
118

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

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

135
    private void register(ApiResponseEntry entry) {
136
        IRI userIri;
137
        try {
138
            userIri = vf.createIRI(entry.get("user"));
×
139
        } catch (IllegalArgumentException ex) {
×
140
            logger.error("Error creating IRI from user string: {}", entry.get("user"), ex);
×
141
            return;
×
142
        }
×
143
        String pubkeyhash = entry.get("pubkeyHash");
×
144
        boolean approved = approvedIdPubkeyhashMap.containsKey(userIri) && approvedIdPubkeyhashMap.get(userIri).contains(pubkeyhash);
×
145
        boolean authoritative = "true".equals(entry.get("authoritative"));
×
146
        IRI introNpIri = null;
×
147
        try {
148
            introNpIri = vf.createIRI(entry.get("intronp"));
×
149
        } catch (IllegalArgumentException ex) {
×
150
            logger.error("Error creating IRI from intronp string: {}", entry.get("intronp"), ex);
×
151
        }
×
152
        IRI keyLocation = null;
×
153
        try {
154
            if (!entry.get("keyLocation").isEmpty()) {
×
155
                keyLocation = vf.createIRI(entry.get("keyLocation"));
×
156
            }
157
        } catch (IllegalArgumentException ex) {
×
158
            logger.error("Error creating IRI from keyLocation string: {}", entry.get("keyLocation"), ex);
×
159
        }
×
160
        if (approved) {
×
161
            if (authoritative) {
×
162
                if (introNpIri != null) approvedIntros.add(introNpIri);
×
163
                if (keyLocation != null) addValue(approvedPubkeyhashLocationMap, pubkeyhash, keyLocation);
×
164
            }
165
        } else {
166
            addValue(unapprovedIdPubkeyhashMap, userIri, entry.get("pubkeyHash"));
×
167
            addValue(unapprovedPubkeyhashIdMap, entry.get("pubkeyHash"), userIri);
×
168
            if (keyLocation != null) addValue(unapprovedPubkeyhashLocationMap, pubkeyhash, keyLocation);
×
169
        }
170
        if (introNpIri != null) {
×
171
            addValue(pubkeyhashIntroMap, entry.get("pubkeyHash"), introNpIri);
×
172
        }
173
        String name = entry.get("name");
×
174
        if (!name.isEmpty() && !idNameMap.containsKey(userIri)) {
×
175
            idNameMap.put(userIri, name);
×
176
        }
177
    }
×
178

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

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

235
    private void addValue(Map<String, Set<IRI>> map, String key, IRI value) {
236
        Set<IRI> values = map.get(key);
5✔
237
        if (values == null) {
2✔
238
            values = new HashSet<>();
4✔
239
            map.put(key, values);
5✔
240
        }
241
        values.add(value);
4✔
242
    }
1✔
243

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

250
//        private static boolean hasValue(Map<String,Set<IRI>> map, String key, IRI value) {
251
//                Set<IRI> values = map.get(key);
252
//                if (values == null) return false;
253
//                return values.contains(value);
254
//        }
255

256
    /**
257
     * Checks if the given IRI is a user identifier.
258
     *
259
     * @param userIri the IRI to check
260
     * @return true if the IRI is a user identifier, false otherwise
261
     */
262
    public boolean isUser(IRI userIri) {
263
        return approvedIdPubkeyhashMap.containsKey(userIri) || unapprovedIdPubkeyhashMap.containsKey(userIri);
×
264
    }
265

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

282
    /**
283
     * Checks if the given public key is approved for the specified user.
284
     *
285
     * @param pubkeyhash the public key to check
286
     * @param user       the IRI of the user to check against
287
     * @return true if the key is approved for the user, false otherwise
288
     */
289
    public boolean isApprovedPubkeyhashForUser(String pubkeyhash, IRI user) {
290
        return hasValue(approvedIdPubkeyhashMap, user, pubkeyhash);
×
291
    }
292

293
    private String getShortName(IRI userIri) {
294
        if (userIri == null) return "(unknown)";
×
295
        String n = userIri.stringValue();
×
296
        n = n.replaceFirst("^https://orcid.org/", "");
×
297
        if (n.length() > 40) return n.substring(0, 30) + "...";
×
298
        return n;
×
299
    }
300

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

318
    /**
319
     * Retrieves the IRI of the owner of a nanopublication's signature.
320
     *
321
     * @param np the nanopublication
322
     * @return the IRI of the signature owner if found, or null if not found or if an error occurs
323
     */
324
    public IRI getSignatureOwnerIri(Nanopub np) {
325
        try {
326
            if (np != null) {
2!
327
                NanopubSignatureElement se = SignatureUtils.getSignatureElement(np);
3✔
328
                if (se != null) {
2!
329
                    String pubkeyhash = Utils.createSha256HexHash(se.getPublicKeyString());
×
330
                    return getUserIriForPubkeyhash(pubkeyhash, true);
×
331
                }
332
            }
333
        } catch (MalformedCryptoElementException ex) {
×
334
            logger.error("Error getting signature element", ex);
×
335
        }
1✔
336
        return null;
2✔
337
    }
338

339
    /**
340
     * Retrieves the name of a user based on their IRI.
341
     *
342
     * @param userIri the IRI of the user
343
     * @return the name of the user if found, or null if not found
344
     */
345
    public String getName(IRI userIri) {
346
        return idNameMap.get(userIri);
6✔
347
    }
348

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

363
    /**
364
     * Retrieves a short display name for a user based on their IRI.
365
     *
366
     * @param userIri the IRI of the user
367
     * @return the short display name of the user, which is either their name or their short name
368
     */
369
    public String getShortDisplayName(IRI userIri) {
370
        String name = getName(userIri);
×
371
        if (name != null && !name.isEmpty()) {
×
372
            return name;
×
373
        }
374
        return getShortName(userIri);
×
375
    }
376

377
    /**
378
     * Retrieves a short display name for a user based on their IRI and public key.
379
     *
380
     * @param userIri    the IRI of the user
381
     * @param pubkeyhash the public key of the user
382
     * @return the short display name of the user, which may include a contested identity note if multiple identities are associated with the public key
383
     */
384
    public String getShortDisplayNameForPubkeyhash(IRI userIri, String pubkeyhash) {
385
        Set<IRI> ids = approvedPubkeyhashIdMap.get(pubkeyhash);
×
386
        if (ids == null || ids.isEmpty()) {
×
387
            ids = unapprovedPubkeyhashIdMap.get(pubkeyhash);
×
388
            if (ids == null || ids.isEmpty()) {
×
389
                return getShortName(userIri);
×
390
            } else if (ids.size() == 1) {
×
391
                return getShortDisplayName(ids.iterator().next());
×
392
            } else {
393
                return getShortName(userIri) + " (contested identity)";
×
394
            }
395
        } else if (ids.size() == 1) {
×
396
            return getShortDisplayName(ids.iterator().next());
×
397
        } else {
398
            return "(contested identity)";
×
399
        }
400
    }
401

402
    /**
403
     * Finds a single user ID for a given public key.
404
     *
405
     * @param pubkeyhash the public key to search for
406
     * @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
407
     */
408
    public IRI findSingleIdForPubkeyhash(String pubkeyhash) {
409
        if (approvedPubkeyhashIdMap.containsKey(pubkeyhash) && !approvedPubkeyhashIdMap.get(pubkeyhash).isEmpty()) {
×
410
            if (approvedPubkeyhashIdMap.get(pubkeyhash).size() == 1) {
×
411
                return approvedPubkeyhashIdMap.get(pubkeyhash).iterator().next();
×
412
            } else {
413
                return null;
×
414
            }
415
        }
416
        if (unapprovedPubkeyhashIdMap.containsKey(pubkeyhash) && !unapprovedPubkeyhashIdMap.get(pubkeyhash).isEmpty()) {
×
417
            if (unapprovedPubkeyhashIdMap.get(pubkeyhash).size() == 1) {
×
418
                return unapprovedPubkeyhashIdMap.get(pubkeyhash).iterator().next();
×
419
            } else {
420
                return null;
×
421
            }
422
        }
423
        return null;
×
424
    }
425

426
    /**
427
     * Comparator for sorting users by their display names in a case-insensitive manner.
428
     */
429
    public final transient Comparator<IRI> userComparator = (iri1, iri2) -> getDisplayName(iri1).toLowerCase().compareTo(getDisplayName(iri2).toLowerCase());
4✔
430

431
    /**
432
     * Retrieves a list of users, either approved or unapproved.
433
     *
434
     * @param approved if true, retrieves approved users; if false, retrieves unapproved users
435
     * @return a sorted list of user IRIs
436
     */
437
    public List<IRI> getUsers(boolean approved) {
438
        List<IRI> list;
439
        if (approved) {
×
440
            list = new ArrayList<IRI>(approvedIdPubkeyhashMap.keySet());
×
441
        } else {
442
            list = new ArrayList<IRI>();
×
443
            for (IRI u : unapprovedIdPubkeyhashMap.keySet()) {
×
444
                if (!approvedIdPubkeyhashMap.containsKey(u)) list.add(u);
×
445
            }
×
446
        }
447
        // TODO Cache the sorted list to not sort from scratch each time:
448
        list.sort(userComparator);
×
449
        return list;
×
450
    }
451

452
    /**
453
     * Retrieves a list of public keys for a given user.
454
     *
455
     * @param user     the IRI of the user whose public keys are to be retrieved
456
     * @param approved if true, retrieves approved public keys; if false, retrieves unapproved public keys
457
     * @return a list of public keys associated with the user, either approved or unapproved
458
     */
459
    public List<String> getPubkeyhashes(IRI user, Boolean approved) {
460
        List<String> pubkeys = new ArrayList<>();
4✔
461
        if (user != null) {
2!
462
            if (approved == null || approved) {
5!
463
                if (approvedIdPubkeyhashMap.containsKey(user)) pubkeys.addAll(approvedIdPubkeyhashMap.get(user));
13!
464
            }
465
            if (approved == null || !approved) {
5!
466
                if (unapprovedIdPubkeyhashMap.containsKey(user)) pubkeys.addAll(unapprovedIdPubkeyhashMap.get(user));
×
467
            }
468
        }
469
        return pubkeys;
2✔
470
    }
471

472
    /**
473
     * Retrieves a list of introduction nanopublications for a given user.
474
     *
475
     * @param user the IRI of the user whose introduction nanopublications are to be retrieved
476
     * @return a list of introduction nanopublications associated with the user, sorted by creation time
477
     */
478
    public List<IntroNanopub> getIntroNanopubs(IRI user) {
479
        if (introNanopubLists.containsKey(user)) return introNanopubLists.get(user);
×
480

481
        Map<IRI, IntroNanopub> introNps = new HashMap<>();
×
482
        if (approvedIdPubkeyhashMap.containsKey(user)) {
×
483
            for (String pk : approvedIdPubkeyhashMap.get(user)) {
×
484
                getIntroNanopubs(pk, introNps);
×
485
            }
×
486
        }
487
        if (unapprovedIdPubkeyhashMap.containsKey(user)) {
×
488
            for (String pk : unapprovedIdPubkeyhashMap.get(user)) {
×
489
                getIntroNanopubs(pk, introNps);
×
490
            }
×
491
        }
492
        List<IntroNanopub> list = new ArrayList<>(introNps.values());
×
493
        list.sort((i0, i1) -> {
×
494
            Calendar c0 = SimpleTimestampPattern.getCreationTime(i0.getNanopub());
×
495
            Calendar c1 = SimpleTimestampPattern.getCreationTime(i1.getNanopub());
×
496
            if (c0 == null && c1 == null) return 0;
×
497
            if (c0 == null) return 1;
×
498
            if (c1 == null) return -1;
×
499
            return -c0.compareTo(c1);
×
500
        });
501
        introNanopubLists.put(user, list);
×
502
        return list;
×
503
    }
504

505
    /**
506
     * Retrieves a map of introduction nanopublications for a given public key.
507
     *
508
     * @param pubkey the public key for which introduction nanopublications are to be retrieved
509
     * @return a map where the keys are IRI identifiers of introduction nanopublications and the values are the corresponding IntroNanopub objects
510
     */
511
    public Map<IRI, IntroNanopub> getIntroNanopubs(String pubkey) {
512
        Map<IRI, IntroNanopub> introNps = new HashMap<>();
×
513
        getIntroNanopubs(pubkey, introNps);
×
514
        return introNps;
×
515
    }
516

517
    private void getIntroNanopubs(String pubkeyhash, Map<IRI, IntroNanopub> introNps) {
518
        if (pubkeyhashIntroMap.containsKey(pubkeyhash)) {
×
519
            for (IRI iri : pubkeyhashIntroMap.get(pubkeyhash)) {
×
520
                IntroNanopub introNp = toIntroNanopub(iri);
×
521
                if (introNp != null) {
×
522
                    introNps.put(iri, introNp);
×
523
                }
524
            }
×
525
        }
526
    }
×
527

528
    /**
529
     * Checks if the given introduction nanopublication is approved.
530
     *
531
     * @param in the introduction nanopublication to check
532
     * @return true if the introduction nanopublication is approved, false otherwise
533
     */
534
    public boolean isApproved(IntroNanopub in) {
535
        return approvedIntros.contains(in.getNanopub().getUri());
×
536
    }
537

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

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