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

knowledgepixels / nanodash / 20232167416

15 Dec 2025 12:27PM UTC coverage: 15.381% (-0.1%) from 15.509%
20232167416

push

github

tkuhn
fix: Increase wait time after failed API request

592 of 4976 branches covered (11.9%)

Branch coverage included in aggregate %.

1572 of 9093 relevant lines covered (17.29%)

2.25 hits per line

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

31.48
src/main/java/com/knowledgepixels/nanodash/Space.java
1
package com.knowledgepixels.nanodash;
2

3
import com.github.jsonldjava.shaded.com.google.common.collect.Ordering;
4
import com.google.common.collect.ArrayListMultimap;
5
import com.google.common.collect.Multimap;
6
import com.knowledgepixels.nanodash.template.Template;
7
import com.knowledgepixels.nanodash.template.TemplateData;
8
import com.knowledgepixels.nanodash.vocabulary.KPXL_TERMS;
9
import jakarta.xml.bind.DatatypeConverter;
10
import org.eclipse.rdf4j.model.IRI;
11
import org.eclipse.rdf4j.model.Literal;
12
import org.eclipse.rdf4j.model.Statement;
13
import org.eclipse.rdf4j.model.vocabulary.DCTERMS;
14
import org.eclipse.rdf4j.model.vocabulary.OWL;
15
import org.nanopub.Nanopub;
16
import org.nanopub.extra.services.ApiResponse;
17
import org.nanopub.extra.services.ApiResponseEntry;
18
import org.nanopub.extra.services.QueryRef;
19
import org.nanopub.vocabulary.NTEMPLATE;
20
import org.slf4j.Logger;
21
import org.slf4j.LoggerFactory;
22

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

26
/**
27
 * Class representing a "Space", which can be any kind of collaborative unit, like a project, group, or event.
28
 */
29
public class Space extends ProfiledResource {
30

31
    private static final Logger logger = LoggerFactory.getLogger(Space.class);
9✔
32

33
    private static List<Space> spaceList;
34
    private static Map<String, List<Space>> spaceListByType;
35
    private static Map<String, Space> spacesByCoreInfo = new HashMap<>();
12✔
36
    private static Map<String, Space> spacesById;
37
    private static Map<Space, Set<Space>> subspaceMap;
38
    private static Map<Space, Set<Space>> superspaceMap;
39
    private static boolean loaded = false;
6✔
40
    private static Long runRootUpdateAfter = null;
9✔
41

42
    /**
43
     * Refresh the list of spaces from the API response.
44
     *
45
     * @param resp The API response containing space data.
46
     */
47
    public static synchronized void refresh(ApiResponse resp) {
48
        spaceList = new ArrayList<>();
12✔
49
        spaceListByType = new HashMap<>();
12✔
50
        Map<String, Space> prevSpacesByCoreInfoPrev = spacesByCoreInfo;
6✔
51
        spacesByCoreInfo = new HashMap<>();
12✔
52
        spacesById = new HashMap<>();
12✔
53
        subspaceMap = new HashMap<>();
12✔
54
        superspaceMap = new HashMap<>();
12✔
55
        for (ApiResponseEntry entry : resp.getData()) {
33✔
56
            Space space = new Space(entry);
15✔
57
            Space prevSpace = prevSpacesByCoreInfoPrev.get(space.getCoreInfoString());
18✔
58
            if (prevSpace != null) space = prevSpace;
6!
59
            spaceList.add(space);
12✔
60
            spaceListByType.computeIfAbsent(space.getType(), k -> new ArrayList<>()).add(space);
39✔
61
            spacesByCoreInfo.put(space.getCoreInfoString(), space);
18✔
62
            spacesById.put(space.getId(), space);
18✔
63
        }
3✔
64
        for (Space space : spaceList) {
30✔
65
            Space superSpace = space.getIdSuperspace();
9✔
66
            if (superSpace == null) continue;
9✔
67
            subspaceMap.computeIfAbsent(superSpace, k -> new HashSet<>()).add(space);
36✔
68
            superspaceMap.computeIfAbsent(space, k -> new HashSet<>()).add(superSpace);
36✔
69
        }
3✔
70
        loaded = true;
6✔
71
    }
3✔
72

73
    /**
74
     * Check if the spaces have been loaded.
75
     *
76
     * @return true if loaded, false otherwise.
77
     */
78
    public static boolean isLoaded() {
79
        return loaded;
×
80
    }
81

82
    public static boolean areAllSpacesInitialized() {
83
        for (Space space : spaceList) {
×
84
            if (!space.isDataInitialized()) return false;
×
85
        }
×
86
        return true;
×
87
    }
88

89
    @Override
90
    public boolean isDataInitialized() {
91
        triggerDataUpdate();
×
92
        return dataInitialized && super.isDataInitialized();
×
93
    }
94

95
    public static void triggerAllDataUpdates() {
96
        for (Space space : spaceList) {
×
97
            space.triggerDataUpdate();
×
98
        }
×
99
    }
×
100

101
    /**
102
     * Ensure that the spaces are loaded, fetching them from the API if necessary.
103
     */
104
    public static void ensureLoaded() {
105
        if (spaceList == null) {
6!
106
            try {
107
                if (runRootUpdateAfter != null) {
×
108
                    while (System.currentTimeMillis() < runRootUpdateAfter) {
×
109
                        Thread.sleep(100);
×
110
                    }
111
                    runRootUpdateAfter = null;
×
112
                }
113
            } catch (InterruptedException ex) {
×
114
                logger.error("Interrupted", ex);
×
115
            }
×
116
            refresh(QueryApiAccess.forcedGet(new QueryRef("get-spaces")));
×
117
        }
118
    }
3✔
119

120
    public static void forceRootRefresh(long waitMillis) {
121
        spaceList = null;
×
122
        runRootUpdateAfter = System.currentTimeMillis() + waitMillis;
×
123
    }
×
124

125
    /**
126
     * Get the list of all spaces.
127
     *
128
     * @return List of spaces.
129
     */
130
    public static List<Space> getSpaceList() {
131
        ensureLoaded();
×
132
        return spaceList;
×
133
    }
134

135
    /**
136
     * Get the list of spaces of a specific type.
137
     *
138
     * @param type The type of spaces to retrieve.
139
     *             System.err.println("REFRESH...");
140
     * @return List of spaces of the specified type.
141
     */
142
    public static List<Space> getSpaceList(String type) {
143
        ensureLoaded();
×
144
        return spaceListByType.computeIfAbsent(type, k -> new ArrayList<>());
×
145
    }
146

147
    /**
148
     * Get a space by its id.
149
     *
150
     * @param id The id of the space.
151
     * @return The corresponding Space object, or null if not found.
152
     */
153
    public static Space get(String id) {
154
        ensureLoaded();
3✔
155
        return spacesById.get(id);
15✔
156
    }
157

158
    /**
159
     * Mark all spaces as needing a data update.
160
     */
161
    public static void refresh() {
162
        refresh(QueryApiAccess.forcedGet(new QueryRef("get-spaces")));
18✔
163
        for (Space space : spaceList) {
30✔
164
            space.dataNeedsUpdate = true;
9✔
165
        }
3✔
166
    }
3✔
167

168
    public void forceRefresh(long waitMillis) {
169
        super.forceRefresh(waitMillis);
×
170
        dataNeedsUpdate = true;
×
171
        dataInitialized = false;
×
172
    }
×
173

174
    private String label, rootNanopubId, type;
175
    private Nanopub rootNanopub = null;
9✔
176
    private SpaceData data = new SpaceData();
15✔
177

178
    private static class SpaceData implements Serializable {
6✔
179

180
        List<String> altIds = new ArrayList<>();
15✔
181

182
        String description = null;
9✔
183
        Calendar startDate, endDate;
184
        IRI defaultProvenance = null;
9✔
185

186
        List<IRI> admins = new ArrayList<>();
15✔
187
        Map<IRI, Set<SpaceMemberRoleRef>> users = new HashMap<>();
15✔
188
        List<SpaceMemberRoleRef> roles = new ArrayList<>();
15✔
189
        Map<IRI, SpaceMemberRole> roleMap = new HashMap<>();
15✔
190

191
        Map<String, IRI> adminPubkeyMap = new HashMap<>();
15✔
192
        Set<Serializable> pinnedResources = new HashSet<>();
15✔
193
        Set<String> pinGroupTags = new HashSet<>();
15✔
194
        Map<String, Set<Serializable>> pinnedResourceMap = new HashMap<>();
18✔
195

196
        void addAdmin(IRI admin, String npId) {
197
            // TODO This isn't efficient for long owner lists:
198
            if (admins.contains(admin)) return;
15!
199
            admins.add(admin);
15✔
200
            UserData ud = User.getUserData();
6✔
201
            for (String pubkeyhash : ud.getPubkeyhashes(admin, true)) {
42✔
202
                adminPubkeyMap.put(pubkeyhash, admin);
18✔
203
            }
3✔
204
            users.computeIfAbsent(admin, (k) -> new HashSet<>()).add(new SpaceMemberRoleRef(SpaceMemberRole.ADMIN_ROLE, npId));
51✔
205
        }
3✔
206

207
    }
208

209
    private boolean dataInitialized = false;
9✔
210
    private boolean dataNeedsUpdate = true;
9✔
211

212
    private Space(ApiResponseEntry resp) {
213
        super(resp.get("space"));
15✔
214
        initSpace(this);
9✔
215
        this.label = resp.get("label");
15✔
216
        this.type = resp.get("type");
15✔
217
        this.rootNanopubId = resp.get("np");
15✔
218
        this.rootNanopub = Utils.getAsNanopub(rootNanopubId);
15✔
219
        setCoreData(data);
12✔
220
    }
3✔
221

222
    /**
223
     * Get the root nanopublication ID of the space.
224
     *
225
     * @return The root nanopub ID.
226
     */
227
    @Override
228
    public String getNanopubId() {
229
        return rootNanopubId;
×
230
    }
231

232
    /**
233
     * Get a string combining the space ID and root nanopub ID for core identification.
234
     *
235
     * @return The core info string.
236
     */
237
    public String getCoreInfoString() {
238
        return getId() + " " + rootNanopubId;
18✔
239
    }
240

241
    /**
242
     * Get the root nanopublication of the space.
243
     *
244
     * @return The root Nanopub object.
245
     */
246
    @Override
247
    public Nanopub getNanopub() {
248
        return rootNanopub;
×
249
    }
250

251
    /**
252
     * Get the label of the space.
253
     *
254
     * @return The space label.
255
     */
256
    public String getLabel() {
257
        return label;
×
258
    }
259

260
    /**
261
     * Get the type of the space.
262
     *
263
     * @return The space type.
264
     */
265
    public String getType() {
266
        return type;
9✔
267
    }
268

269
    /**
270
     * Get the start date of the space.
271
     *
272
     * @return The start date as a Calendar object, or null if not set.
273
     */
274
    public Calendar getStartDate() {
275
        return data.startDate;
×
276
    }
277

278
    /**
279
     * Get the end date of the space.
280
     *
281
     * @return The end date as a Calendar object, or null if not set.
282
     */
283
    public Calendar getEndDate() {
284
        return data.endDate;
×
285
    }
286

287
    /**
288
     * Get a simplified label for the type of space by removing any namespace prefix.
289
     *
290
     * @return The simplified type label.
291
     */
292
    public String getTypeLabel() {
293
        return type.replaceFirst("^.*/", "");
×
294
    }
295

296
    /**
297
     * Get the description of the space.
298
     *
299
     * @return The description string.
300
     */
301
    public String getDescription() {
302
        return data.description;
×
303
    }
304

305

306
    /**
307
     * Get the list of admins in this space.
308
     *
309
     * @return List of admin IRIs.
310
     */
311
    public List<IRI> getAdmins() {
312
        ensureInitialized();
×
313
        return data.admins;
×
314
    }
315

316
    /**
317
     * Get the list of members in this space.
318
     *
319
     * @return List of member IRIs.
320
     */
321
    public List<IRI> getUsers() {
322
        ensureInitialized();
×
323
        List<IRI> users = new ArrayList<IRI>(data.users.keySet());
×
324
        users.sort(User.getUserData().userComparator);
×
325
        return users;
×
326
    }
327

328
    /**
329
     * Get the roles of a specific member in this space.
330
     *
331
     * @param userId The IRI of the member.
332
     * @return Set of roles assigned to the member, or null if the member is not part of this space.
333
     */
334
    public Set<SpaceMemberRoleRef> getMemberRoles(IRI userId) {
335
        ensureInitialized();
×
336
        return data.users.get(userId);
×
337
    }
338

339
    /**
340
     * Check if a user is a member of this space.
341
     *
342
     * @param userId The IRI of the user to check.
343
     * @return true if the user is a member, false otherwise.
344
     */
345
    public boolean isMember(IRI userId) {
346
        ensureInitialized();
×
347
        return data.users.containsKey(userId);
×
348
    }
349

350
    public boolean isAdminPubkey(String pubkey) {
351
        ensureInitialized();
×
352
        return data.adminPubkeyMap.containsKey(pubkey);
×
353
    }
354

355
    /**
356
     * Get the list of pinned resources in this space.
357
     *
358
     * @return List of pinned resources.
359
     */
360
    public Set<Serializable> getPinnedResources() {
361
        ensureInitialized();
×
362
        return data.pinnedResources;
×
363
    }
364

365
    /**
366
     * Get the set of tags used for grouping pinned resources.
367
     *
368
     * @return Set of tags.
369
     */
370
    public Set<String> getPinGroupTags() {
371
        ensureInitialized();
×
372
        return data.pinGroupTags;
×
373
    }
374

375
    /**
376
     * Get a map of pinned resources grouped by their tags.
377
     *
378
     * @return Map where keys are tags and values are lists of pinned resources (Templates or GrlcQueries).
379
     */
380
    public Map<String, Set<Serializable>> getPinnedResourceMap() {
381
        ensureInitialized();
×
382
        return data.pinnedResourceMap;
×
383
    }
384

385
    public boolean appliesTo(String elementId, Set<IRI> classes) {
386
        triggerDataUpdate();
×
387
        for (ViewDisplay v : getViewDisplays()) {
×
388
            if (v.appliesTo(elementId, classes)) return true;
×
389
        }
×
390
        return false;
×
391
    }
392

393
    /**
394
     * Get the default provenance IRI for this space.
395
     *
396
     * @return The default provenance IRI, or null if not set.
397
     */
398
    public IRI getDefaultProvenance() {
399
        return data.defaultProvenance;
×
400
    }
401

402
    /**
403
     * Get the roles defined in this space.
404
     *
405
     * @return List of roles.
406
     */
407
    public List<SpaceMemberRoleRef> getRoles() {
408
        return data.roles;
×
409
    }
410

411
    /**
412
     * Get the super ID of the space.
413
     *
414
     * @return Always returns null. Use getIdSuperspace() instead.
415
     */
416
    public String getSuperId() {
417
        return null;
×
418
    }
419

420
    /**
421
     * Get the superspace ID.
422
     *
423
     * @return The superspace, or null if not applicable.
424
     */
425
    public Space getIdSuperspace() {
426
        if (!getId().matches("https?://[^/]+/.*/[^/]*/?")) return null;
15!
427
        String superId = getId().replaceFirst("(https?://[^/]+/.*)/[^/]*/?", "$1");
18✔
428
        if (spacesById.containsKey(superId)) {
12✔
429
            return spacesById.get(superId);
15✔
430
        }
431
        return null;
6✔
432
    }
433

434
    /**
435
     * Get superspaces of this space.
436
     *
437
     * @return List of superspaces.
438
     */
439
    public List<Space> getSuperspaces() {
440
        if (superspaceMap.containsKey(this)) {
×
441
            List<Space> superspaces = new ArrayList<>(superspaceMap.get(this));
×
442
            Collections.sort(superspaces, Ordering.usingToString());
×
443
            return superspaces;
×
444
        }
445
        return new ArrayList<>();
×
446
    }
447

448
    /**
449
     * Get subspaces of this space.
450
     *
451
     * @return List of subspaces.
452
     */
453
    public List<Space> getSubspaces() {
454
        if (subspaceMap.containsKey(this)) {
×
455
            List<Space> subspaces = new ArrayList<>(subspaceMap.get(this));
×
456
            Collections.sort(subspaces, Ordering.usingToString());
×
457
            return subspaces;
×
458
        }
459
        return new ArrayList<>();
×
460
    }
461

462
    /**
463
     * Get subspaces of a specific type.
464
     *
465
     * @param type The type of subspaces to retrieve.
466
     * @return List of subspaces of the specified type.
467
     */
468
    public List<Space> getSubspaces(String type) {
469
        List<Space> l = new ArrayList<>();
×
470
        for (Space s : getSubspaces()) {
×
471
            if (s.getType().equals(type)) l.add(s);
×
472
        }
×
473
        return l;
×
474
    }
475

476
    /**
477
     * Get alternative IDs for the space.
478
     *
479
     * @return List of alternative IDs.
480
     */
481
    public List<String> getAltIDs() {
482
        return data.altIds;
×
483
    }
484

485
    private synchronized void ensureInitialized() {
486
        Thread thread = triggerSpaceDataUpdate();
×
487
        if (!dataInitialized && thread != null) {
×
488
            try {
489
                thread.join();
×
490
            } catch (InterruptedException ex) {
×
491
                logger.error("failed to join thread", ex);
×
492
            }
×
493
        }
494
        thread = super.triggerDataUpdate();
×
495
        if (!dataInitialized && thread != null) {
×
496
            try {
497
                thread.join();
×
498
            } catch (InterruptedException ex) {
×
499
                logger.error("failed to join thread", ex);
×
500
            }
×
501
        }
502
    }
×
503

504
    @Override
505
    protected synchronized Thread triggerDataUpdate() {
506
        triggerSpaceDataUpdate();
×
507
        return super.triggerDataUpdate();
×
508
    }
509

510
    private synchronized Thread triggerSpaceDataUpdate() {
511
        if (dataNeedsUpdate) {
×
512
            Thread thread = new Thread(() -> {
×
513
                try {
514
                    if (getRunUpdateAfter() != null) {
×
515
                        while (System.currentTimeMillis() < getRunUpdateAfter()) {
×
516
                            Thread.sleep(100);
×
517
                        }
518
                    }
519
                    SpaceData newData = new SpaceData();
×
520
                    setCoreData(newData);
×
521

522
                    newData.roles.add(new SpaceMemberRoleRef(SpaceMemberRole.ADMIN_ROLE, null));
×
523
                    newData.roleMap.put(KPXL_TERMS.HAS_ADMIN_PREDICATE, SpaceMemberRole.ADMIN_ROLE);
×
524

525
                    // TODO Improve this:
526
                    Multimap<String, String> spaceIds = ArrayListMultimap.create();
×
527
                    Multimap<String, String> resourceIds = ArrayListMultimap.create();
×
528
                    spaceIds.put("space", getId());
×
529
                    resourceIds.put("resource", getId());
×
530
                    for (String id : newData.altIds) {
×
531
                        spaceIds.put("space", id);
×
532
                        resourceIds.put("resource", id);
×
533
                    }
×
534

535
                    ApiResponse getAdminsResponse = QueryApiAccess.get(new QueryRef("get-admins", spaceIds));
×
536
                    boolean continueAddingAdmins = true;
×
537
                    while (continueAddingAdmins) {
×
538
                        continueAddingAdmins = false;
×
539
                        for (ApiResponseEntry r : getAdminsResponse.getData()) {
×
540
                            String pubkeyhash = r.get("pubkey");
×
541
                            if (newData.adminPubkeyMap.containsKey(pubkeyhash)) {
×
542
                                IRI adminId = Utils.vf.createIRI(r.get("admin"));
×
543
                                if (!newData.admins.contains(adminId)) {
×
544
                                    continueAddingAdmins = true;
×
545
                                    newData.addAdmin(adminId, r.get("np"));
×
546
                                }
547
                            }
548
                        }
×
549
                    }
550
                    newData.admins.sort(User.getUserData().userComparator);
×
551

552
                    Multimap<String, String> getSpaceMemberParams = ArrayListMultimap.create(spaceIds);
×
553

554
                    for (ApiResponseEntry r : QueryApiAccess.get(new QueryRef("get-space-member-roles", spaceIds)).getData()) {
×
555
                        if (!newData.adminPubkeyMap.containsKey(r.get("pubkey"))) continue;
×
556
                        SpaceMemberRole role = new SpaceMemberRole(r);
×
557
                        newData.roles.add(new SpaceMemberRoleRef(role, r.get("np")));
×
558

559
                        // TODO Handle cases of overlapping properties:
560
                        for (IRI p : role.getRegularProperties()) newData.roleMap.put(p, role);
×
561
                        for (IRI p : role.getInverseProperties()) newData.roleMap.put(p, role);
×
562

563
                        role.addRoleParams(getSpaceMemberParams);
×
564
                    }
×
565

566
                    for (ApiResponseEntry r : QueryApiAccess.get(new QueryRef("get-space-members", getSpaceMemberParams)).getData()) {
×
567
                        IRI memberId = Utils.vf.createIRI(r.get("member"));
×
568
                        SpaceMemberRole role = newData.roleMap.get(Utils.vf.createIRI(r.get("role")));
×
569
                        newData.users.computeIfAbsent(memberId, (k) -> new HashSet<>()).add(new SpaceMemberRoleRef(role, r.get("np")));
×
570
                    }
×
571

572
                    for (ApiResponseEntry r : QueryApiAccess.get(new QueryRef("get-pinned-templates", spaceIds)).getData()) {
×
573
                        if (!newData.adminPubkeyMap.containsKey(r.get("pubkey"))) continue;
×
574
                        Template t = TemplateData.get().getTemplate(r.get("template"));
×
575
                        if (t == null) continue;
×
576
                        newData.pinnedResources.add(t);
×
577
                        String tag = r.get("tag");
×
578
                        if (tag != null && !tag.isEmpty()) {
×
579
                            newData.pinGroupTags.add(r.get("tag"));
×
580
                            newData.pinnedResourceMap.computeIfAbsent(tag, k -> new HashSet<>()).add(TemplateData.get().getTemplate(r.get("template")));
×
581
                        }
582
                    }
×
583
                    for (ApiResponseEntry r : QueryApiAccess.get(new QueryRef("get-pinned-queries", spaceIds)).getData()) {
×
584
                        if (!newData.adminPubkeyMap.containsKey(r.get("pubkey"))) continue;
×
585
                        GrlcQuery query = GrlcQuery.get(r.get("query"));
×
586
                        if (query == null) continue;
×
587
                        newData.pinnedResources.add(query);
×
588
                        String tag = r.get("tag");
×
589
                        if (tag != null && !tag.isEmpty()) {
×
590
                            newData.pinGroupTags.add(r.get("tag"));
×
591
                            newData.pinnedResourceMap.computeIfAbsent(tag, k -> new HashSet<>()).add(query);
×
592
                        }
593
                    }
×
594
                    data = newData;
×
595
                    dataInitialized = true;
×
596
                } catch (Exception ex) {
×
597
                    logger.error("Error while trying to update space data: {}", ex);
×
598
                }
×
599
            });
×
600
            thread.start();
×
601
            dataNeedsUpdate = false;
×
602
            return thread;
×
603
        }
604
        return null;
×
605
    }
606

607
    private void setCoreData(SpaceData data) {
608
        for (Statement st : rootNanopub.getAssertion()) {
36✔
609
            if (st.getSubject().stringValue().equals(getId())) {
21!
610
                if (st.getPredicate().equals(OWL.SAMEAS) && st.getObject() instanceof IRI objIri) {
42!
611
                    data.altIds.add(objIri.stringValue());
21✔
612
                } else if (st.getPredicate().equals(DCTERMS.DESCRIPTION)) {
15✔
613
                    data.description = st.getObject().stringValue();
18✔
614
                } else if (st.getPredicate().stringValue().equals("http://schema.org/startDate")) {
18✔
615
                    try {
616
                        data.startDate = DatatypeConverter.parseDateTime(st.getObject().stringValue());
18✔
617
                    } catch (IllegalArgumentException ex) {
×
618
                        logger.error("Failed to parse date {}", st.getObject().stringValue());
×
619
                    }
3✔
620
                } else if (st.getPredicate().stringValue().equals("http://schema.org/endDate")) {
18✔
621
                    try {
622
                        data.endDate = DatatypeConverter.parseDateTime(st.getObject().stringValue());
18✔
623
                    } catch (IllegalArgumentException ex) {
×
624
                        logger.error("Failed to parse date {}", st.getObject().stringValue());
×
625
                    }
3✔
626
                } else if (st.getPredicate().equals(KPXL_TERMS.HAS_ADMIN) && st.getObject() instanceof IRI obj) {
42!
627
                    data.addAdmin(obj, rootNanopub.getUri().stringValue());
24✔
628
                } else if (st.getPredicate().equals(KPXL_TERMS.HAS_PINNED_TEMPLATE) && st.getObject() instanceof IRI obj) {
15!
629
                    data.pinnedResources.add(TemplateData.get().getTemplate(obj.stringValue()));
×
630
                } else if (st.getPredicate().equals(KPXL_TERMS.HAS_PINNED_QUERY) && st.getObject() instanceof IRI obj) {
15!
631
                    data.pinnedResources.add(GrlcQuery.get(obj.stringValue()));
×
632
                } else if (st.getPredicate().equals(NTEMPLATE.HAS_DEFAULT_PROVENANCE) && st.getObject() instanceof IRI obj) {
15!
633
                    data.defaultProvenance = obj;
3✔
634
                }
635
            } else if (st.getPredicate().equals(NTEMPLATE.HAS_TAG) && st.getObject() instanceof Literal l) {
×
636
                data.pinGroupTags.add(l.stringValue());
×
637
                Set<Serializable> list = data.pinnedResourceMap.get(l.stringValue());
×
638
                if (list == null) {
×
639
                    list = new HashSet<>();
×
640
                    data.pinnedResourceMap.put(l.stringValue(), list);
×
641
                }
642
                list.add(TemplateData.get().getTemplate(st.getSubject().stringValue()));
×
643
            }
644
        }
3✔
645
    }
3✔
646

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