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

knowledgepixels / nanodash / 17402557487

02 Sep 2025 11:49AM UTC coverage: 12.071% (+0.05%) from 12.023%
17402557487

push

github

tkuhn
Continue on project page development: load and show owners/members

331 of 3866 branches covered (8.56%)

Branch coverage included in aggregate %.

969 of 6904 relevant lines covered (14.04%)

0.62 hits per line

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

6.04
src/main/java/com/knowledgepixels/nanodash/Project.java
1
package com.knowledgepixels.nanodash;
2

3
import static com.knowledgepixels.nanodash.Utils.vf;
4

5
import java.io.Serializable;
6
import java.util.ArrayList;
7
import java.util.HashSet;
8
import java.util.List;
9
import java.util.Set;
10
import java.util.concurrent.ConcurrentHashMap;
11
import java.util.concurrent.ConcurrentMap;
12

13
import org.eclipse.rdf4j.model.IRI;
14
import org.eclipse.rdf4j.model.Literal;
15
import org.eclipse.rdf4j.model.Statement;
16
import org.eclipse.rdf4j.model.vocabulary.DCTERMS;
17
import org.nanopub.Nanopub;
18
import org.nanopub.extra.services.ApiResponse;
19
import org.nanopub.extra.services.ApiResponseEntry;
20
import org.nanopub.vocabulary.NTEMPLATE;
21

22
import com.knowledgepixels.nanodash.template.Template;
23
import com.knowledgepixels.nanodash.template.TemplateData;
24

25
/**
26
 * Class representing a Nanodash project.
27
 */
28
public class Project implements Serializable {
29

30
    /**
31
     * The predicate for the owner of the project.
32
     */
33
    public static final IRI HAS_OWNER = vf.createIRI("https://w3id.org/kpxl/gen/terms/hasOwner");
4✔
34

35
    /**
36
     * The predicate for pinned templates in the project.
37
     */
38
    public static final IRI HAS_PINNED_TEMPLATE = vf.createIRI("https://w3id.org/kpxl/gen/terms/hasPinnedTemplate");
4✔
39

40
    /**
41
     * The predicate for pinned queries in the project.
42
     */
43
    public static final IRI HAS_PINNED_QUERY = vf.createIRI("https://w3id.org/kpxl/gen/terms/hasPinnedQuery");
4✔
44

45
    private static List<Project> projectList = new ArrayList<>();
4✔
46
    private static ConcurrentMap<String,Project> projectsByCoreInfo = new ConcurrentHashMap<>();
4✔
47
    private static ConcurrentMap<String,Project> projectsById = new ConcurrentHashMap<>();
5✔
48

49
    public static synchronized void refresh(ApiResponse resp) {
50
        projectList.clear();
×
51
        ConcurrentMap<String,Project> prevProjectsByCoreInfoPrev = projectsByCoreInfo;
×
52
        projectsByCoreInfo = new ConcurrentHashMap<>();
×
53
        projectsById.clear();
×
54
        for (ApiResponseEntry entry : resp.getData()) {
×
55
            Project project = new Project(entry.get("project"), entry.get("label"), entry.get("np"));
×
56
            Project prevProject = prevProjectsByCoreInfoPrev.get(project.getCoreInfoString());
×
57
            if (prevProject != null) project = prevProject;
×
58
            projectList.add(project);
×
59
            projectsByCoreInfo.put(project.getCoreInfoString(), project);
×
60
            projectsById.put(project.getId(), project);
×
61
        }
×
62
    }
×
63

64
    public static List<Project> getProjectList() {
65
        return projectList;
×
66
    }
67

68
    public static Project get(String id) {
69
        return projectsById.get(id);
×
70
    }
71

72
    public static void refresh() {
73
        for (Project project : projectList) {
6!
74
            project.isDataInitialized = false;
×
75
        }
×
76
    }
1✔
77

78
    private String id, label, rootNanopubId;
79
    private Nanopub rootNanopub = null;
×
80

81
    private String description = null;
×
82
    private List<IRI> owners = new ArrayList<>();
×
83
    private List<IRI> members = new ArrayList<>();
×
84
    private ConcurrentMap<String,IRI> ownerPubkeyMap = new ConcurrentHashMap<>();
×
85
    private List<Template> templates = new ArrayList<>();
×
86
    private Set<String> templateTags = new HashSet<>();
×
87
    private ConcurrentMap<String, List<Template>> templatesPerTag = new ConcurrentHashMap<>();
×
88
    private List<IRI> queryIds = new ArrayList<>();
×
89
    private IRI defaultProvenance = null;
×
90

91
    private boolean isDataInitialized = false;
×
92

93
    private Project(String id, String label, String rootNanopubId) {
×
94
        this.id = id;
×
95
        this.label = label;
×
96
        this.rootNanopubId = rootNanopubId;
×
97
        this.rootNanopub = Utils.getAsNanopub(rootNanopubId);
×
98

99
        for (Statement st : rootNanopub.getAssertion()) {
×
100
            if (st.getSubject().stringValue().equals(getId())) {
×
101
                if (st.getPredicate().equals(DCTERMS.DESCRIPTION)) {
×
102
                    description = st.getObject().stringValue();
×
103
                } else if (st.getPredicate().equals(HAS_OWNER) && st.getObject() instanceof IRI obj) {
×
104
                    addOwner(obj);
×
105
                } else if (st.getPredicate().equals(HAS_PINNED_TEMPLATE) && st.getObject() instanceof IRI obj) {
×
106
                    templates.add(TemplateData.get().getTemplate(obj.stringValue()));
×
107
                } else if (st.getPredicate().equals(HAS_PINNED_QUERY) && st.getObject() instanceof IRI obj) {
×
108
                    queryIds.add(obj);
×
109
                } else if (st.getPredicate().equals(NTEMPLATE.HAS_DEFAULT_PROVENANCE) && st.getObject() instanceof IRI obj) {
×
110
                    defaultProvenance = obj;
×
111
                }
112
            } else if (st.getPredicate().equals(NTEMPLATE.HAS_TAG) && st.getObject() instanceof Literal l) {
×
113
                templateTags.add(l.stringValue());
×
114
                List<Template> list = templatesPerTag.get(l.stringValue());
×
115
                if (list == null) {
×
116
                    list = new ArrayList<>();
×
117
                    templatesPerTag.put(l.stringValue(), list);
×
118
                }
119
                list.add(TemplateData.get().getTemplate(st.getSubject().stringValue()));
×
120
            }
121
        }
×
122

123
    }
×
124

125
    private void addOwner(IRI owner) {
126
        // TODO This isn't efficient for long owner lists:
127
        if (owners.contains(owner)) return;
×
128
        owners.add(owner);
×
129
        UserData ud = User.getUserData();
×
130
        for (String pubkeyhash : ud.getPubkeyhashes(owner, true)) {
×
131
            ownerPubkeyMap.put(pubkeyhash, owner);
×
132
        }
×
133
    }
×
134

135
    public String getId() {
136
        return id;
×
137
    }
138

139
    public String getRootNanopubId() {
140
        return rootNanopubId;
×
141
    }
142

143
    public String getCoreInfoString() {
144
        return id + " " + rootNanopubId;
×
145
    }
146

147
    public Nanopub getRootNanopub() {
148
        return rootNanopub;
×
149
    }
150

151
    public String getLabel() {
152
        return label;
×
153
    }
154

155
    public String getDescription() {
156
        return description;
×
157
    }
158

159
    public List<IRI> getOwners() {
160
        ensureInitialized();
×
161
        return owners;
×
162
    }
163

164
    public List<IRI> getMembers() {
165
        ensureInitialized();
×
166
        return members;
×
167
    }
168

169
    public List<Template> getTemplates() {
170
        return templates;
×
171
    }
172

173
    public Set<String> getTemplateTags() {
174
        return templateTags;
×
175
    }
176

177
    public ConcurrentMap<String, List<Template>> getTemplatesPerTag() {
178
        return templatesPerTag;
×
179
    }
180

181
    public List<IRI> getQueryIds() {
182
        return queryIds;
×
183
    }
184

185
    public IRI getDefaultProvenance() {
186
        return defaultProvenance;
×
187
    }
188

189
    private synchronized void ensureInitialized() {
190
        if (!isDataInitialized) {
×
191
            for (ApiResponseEntry r : QueryApiAccess.forcedGet("get-owners-of-project", "project", id).getData()) {
×
192
                String pubkeyhash = r.get("pubkeyhash");
×
193
                if (ownerPubkeyMap.containsKey(pubkeyhash)) {
×
194
                    addOwner(Utils.vf.createIRI(r.get("owner")));
×
195
                }
196
            }
×
197
            members = new ArrayList<>();
×
198
            for (ApiResponseEntry r : QueryApiAccess.forcedGet("get-members-of-project", "project", id).getData()) {
×
199
                IRI memberId = Utils.vf.createIRI(r.get("member"));
×
200
                // TODO These checks are inefficient for long member lists:
201
                if (owners.contains(memberId)) continue;
×
202
                if (members.contains(memberId)) continue;
×
203
                members.add(memberId);
×
204
            }
×
205
            isDataInitialized = true;
×
206
        }
207
    }
×
208

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