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

knowledgepixels / nanodash / 27127668106

08 Jun 2026 09:14AM UTC coverage: 20.467% (-0.5%) from 20.924%
27127668106

Pull #479

github

web-flow
Merge f10bc9fe9 into 5556185a4
Pull Request #479: About pages for spaces, maintained resources, and users (#478)

1024 of 6405 branches covered (15.99%)

Branch coverage included in aggregate %.

2624 of 11419 relevant lines covered (22.98%)

3.29 hits per line

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

69.44
src/main/java/com/knowledgepixels/nanodash/SpaceMemberRole.java
1
package com.knowledgepixels.nanodash;
2

3
import com.google.common.collect.Multimap;
4
import com.knowledgepixels.nanodash.domain.Space;
5
import com.knowledgepixels.nanodash.template.Template;
6
import com.knowledgepixels.nanodash.template.TemplateData;
7
import com.knowledgepixels.nanodash.vocabulary.KPXL_TERMS;
8
import org.eclipse.rdf4j.model.IRI;
9
import org.nanopub.extra.services.ApiResponseEntry;
10

11
import java.io.Serializable;
12
import java.util.stream.Stream;
13

14
/**
15
 * A role that a space member can have, with associated properties.
16
 */
17
public class SpaceMemberRole implements Serializable {
18

19
    private IRI id;
20
    private String label, name, title;
21
    private Template roleAssignmentTemplate = null;
18✔
22
    private IRI[] regularProperties, inverseProperties;
23
    private IRI tier;
24

25
    /**
26
     * Rank of the "everyone" floor (no role held). Below {@link #OBSERVER_RANK}.
27
     */
28
    public static final int EVERYONE_RANK = 0;
29
    private static final int OBSERVER_RANK = 1;
30
    private static final int MEMBER_RANK = 2;
31
    private static final int MAINTAINER_RANK = 3;
32
    private static final int ADMIN_RANK = 4;
33

34
    /**
35
     * Construct a SpaceMemberRole from an API response entry.
36
     *
37
     * @param e The API response entry.
38
     */
39
    public SpaceMemberRole(ApiResponseEntry e) {
6✔
40
        this.id = Utils.vf.createIRI(e.get("role"));
21✔
41
        this.label = e.get("roleLabel");
15✔
42
        this.name = e.get("roleName");
15✔
43
        this.title = e.get("roleTitle");
15✔
44
        if (e.get("roleAssignmentTemplate") != null && !e.get("roleAssignmentTemplate").isBlank()) {
12!
45
            this.roleAssignmentTemplate = TemplateData.get().getTemplate(e.get("roleAssignmentTemplate"));
×
46
        }
47
        regularProperties = stringToIriArray(e.get("regularProperties"));
18✔
48
        inverseProperties = stringToIriArray(e.get("inverseProperties"));
18✔
49
        this.tier = parseTier(e.get("roleType"));
18✔
50
    }
3✔
51

52
    private SpaceMemberRole(IRI id, String label, String name, String title, Template roleAssignmentTemplate, IRI[] regularProperties, IRI[] inverseProperties, IRI tier) {
6✔
53
        this.id = id;
9✔
54
        this.label = label;
9✔
55
        this.name = name;
9✔
56
        this.title = title;
9✔
57
        this.roleAssignmentTemplate = roleAssignmentTemplate;
9✔
58
        this.regularProperties = regularProperties;
9✔
59
        this.inverseProperties = inverseProperties;
9✔
60
        this.tier = tier;
9✔
61
    }
3✔
62

63
    /**
64
     * Parse the role tier from the {@code roleType} query column (the
65
     * server-materialized {@code npa:hasRoleType} value). Defaults to
66
     * {@link KPXL_TERMS#OBSERVER_ROLE} when absent, matching the server-side
67
     * default for roles that declare no tier subclass.
68
     *
69
     * @param roleType the role-type IRI string, or null/blank
70
     * @return the tier IRI (never null)
71
     */
72
    private static IRI parseTier(String roleType) {
73
        if (roleType == null || roleType.isBlank()) return KPXL_TERMS.OBSERVER_ROLE;
21!
74
        return Utils.vf.createIRI(roleType);
12✔
75
    }
76

77
    /**
78
     * Check if this role is the admin role.
79
     *
80
     * @return True if this role is the admin role, false otherwise.
81
     */
82
    public boolean isAdminRole() {
83
        return id.equals(ADMIN_ROLE_IRI);
15✔
84
    }
85

86
    /**
87
     * Get the IRI of this role.
88
     *
89
     * @return The IRI of this role.
90
     */
91
    public IRI getId() {
92
        return id;
9✔
93
    }
94

95
    /**
96
     * Get the label of this role.
97
     *
98
     * @return The label of this role.
99
     */
100
    public String getLabel() {
101
        return label;
9✔
102
    }
103

104
    /**
105
     * Get the name of this role.
106
     *
107
     * @return The name of this role.
108
     */
109
    public String getName() {
110
        return name;
9✔
111
    }
112

113
    /**
114
     * Get the title of this role.
115
     *
116
     * @return The title of this role.
117
     */
118
    public String getTitle() {
119
        return title;
9✔
120
    }
121

122
    /**
123
     * Get the template used for assigning this role.
124
     *
125
     * @return The template used for assigning this role.
126
     */
127
    public Template getRoleAssignmentTemplate() {
128
        return roleAssignmentTemplate;
×
129
    }
130

131
    /**
132
     * Get the regular properties associated with this role.
133
     *
134
     * @return The regular properties associated with this role.
135
     */
136
    public IRI[] getRegularProperties() {
137
        return regularProperties;
9✔
138
    }
139

140
    /**
141
     * Get the inverse properties associated with this role.
142
     *
143
     * @return The inverse properties associated with this role.
144
     */
145
    public IRI[] getInverseProperties() {
146
        return inverseProperties;
9✔
147
    }
148

149
    /**
150
     * Get the tier (role class) of this role — one of the role-tier IRIs in
151
     * {@link KPXL_TERMS} ({@code ADMIN_ROLE_TYPE} / {@code MAINTAINER_ROLE} /
152
     * {@code MEMBER_ROLE} / {@code OBSERVER_ROLE}).
153
     *
154
     * @return The tier IRI (never null; defaults to observer).
155
     */
156
    public IRI getTier() {
157
        return tier;
9✔
158
    }
159

160
    /**
161
     * Get the numeric rank of this role's tier, for threshold comparisons
162
     * (admin {@literal >} maintainer {@literal >} member {@literal >} observer).
163
     *
164
     * @return The tier rank (1..4).
165
     */
166
    public int getTierRank() {
167
        return tierRank(tier);
12✔
168
    }
169

170
    /**
171
     * Numeric rank of a role-tier IRI, for threshold comparisons. Unknown or
172
     * null tiers (the "everyone" floor) rank below observer.
173
     *
174
     * @param tier a role-tier IRI, or null
175
     * @return the rank: admin=4, maintainer=3, member=2, observer=1, else 0
176
     */
177
    public static int tierRank(IRI tier) {
178
        if (KPXL_TERMS.ADMIN_ROLE_TYPE.equals(tier)) return ADMIN_RANK;
18✔
179
        if (KPXL_TERMS.MAINTAINER_ROLE.equals(tier)) return MAINTAINER_RANK;
18✔
180
        if (KPXL_TERMS.MEMBER_ROLE.equals(tier)) return MEMBER_RANK;
18✔
181
        if (KPXL_TERMS.OBSERVER_ROLE.equals(tier)) return OBSERVER_RANK;
18✔
182
        return EVERYONE_RANK;
6✔
183
    }
184

185
    /**
186
     * Whether the given IRI is one of the known role-tier IRIs (as opposed to a
187
     * specific role IRI). Used to interpret {@code gen:isVisibleTo} objects.
188
     *
189
     * @param iri an IRI, or null
190
     * @return true if the IRI is a role tier
191
     */
192
    public static boolean isTier(IRI iri) {
193
        return KPXL_TERMS.ADMIN_ROLE_TYPE.equals(iri)
21✔
194
                || KPXL_TERMS.MAINTAINER_ROLE.equals(iri)
12✔
195
                || KPXL_TERMS.MEMBER_ROLE.equals(iri)
12✔
196
                || KPXL_TERMS.OBSERVER_ROLE.equals(iri);
15✔
197
    }
198

199
    /**
200
     * Add the role parameters to the given multimap.
201
     *
202
     * @param params The multimap to add the parameters to.
203
     */
204
    public void addRoleParams(Multimap<String, String> params) {
205
        for (IRI p : regularProperties) params.put("role", p.stringValue());
69✔
206
        for (IRI p : inverseProperties) params.put("invrole", p.stringValue());
69✔
207
    }
3✔
208

209

210
    private static final IRI ADMIN_ROLE_IRI = Utils.vf.createIRI("https://w3id.org/np/RA_eEJjQbxzSqYSwPzfjzOZi5sMPpUmHskFNsgJYSws8I/adminRole");
12✔
211
    private static final String ADMIN_ROLE_ASSIGNMENT_TEMPLATE_ID = "https://w3id.org/np/RAsOQ7k3GNnuUqZuLm57PWwWopQJR_4onnCpNR457CZg8";
212

213
    /**
214
     * The predefined admin role.
215
     */
216
    public static final SpaceMemberRole ADMIN_ROLE = new SpaceMemberRole(ADMIN_ROLE_IRI, "Admin role", "admin", "Admins", TemplateData.get().getTemplate(ADMIN_ROLE_ASSIGNMENT_TEMPLATE_ID), new IRI[]{}, new IRI[]{KPXL_TERMS.HAS_ADMIN_PREDICATE}, KPXL_TERMS.ADMIN_ROLE_TYPE);
63✔
217

218
    /**
219
     * Convert a space-separated string of IRIs to an array of IRI objects.
220
     *
221
     * @param string The space-separated string of IRIs.
222
     * @return An array of IRI objects.
223
     */
224
    private static IRI[] stringToIriArray(String string) {
225
        if (string == null || string.isBlank()) return new IRI[]{};
24!
226
        return Stream.of(string.split(" ")).map(Utils.vf::createIRI).toArray(IRI[]::new);
51✔
227
    }
228

229
    /**
230
     * Check if the current user is a member of the given space.
231
     *
232
     * @param space The space to check.
233
     * @return True if the current user is a member of the space, false otherwise.
234
     */
235
    public static boolean isCurrentUserMember(Space space) {
236
        if (space == null) return false;
×
237
        IRI userIri = NanodashSession.get().getUserIri();
×
238
        if (userIri == null) return false;
×
239
        return space.isMember(userIri);
×
240
    }
241

242
    /**
243
     * Check if the current user is an admin of the given space.
244
     *
245
     * @param space The space to check.
246
     * @return True if the current user is an admin of the space, false otherwise.
247
     */
248
    public static boolean isCurrentUserAdmin(Space space) {
249
        if (space == null) return false;
×
250
        IRI userIri = NanodashSession.get().getUserIri();
×
251
        if (userIri == null) return false;
×
252
        if (space.getMemberRoles(userIri) == null) return false;
×
253
        for (SpaceMemberRoleRef spaceMemberRoleRef : space.getMemberRoles(userIri)) {
×
254
            if (spaceMemberRoleRef.getRole().isAdminRole()) return true;
×
255
        }
×
256
        return false;
×
257
    }
258

259
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc