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

knowledgepixels / nanodash / 19366908152

14 Nov 2025 02:02PM UTC coverage: 14.317% (+0.4%) from 13.87%
19366908152

push

github

tkuhn
feat: "refresh-upon-publish" PublishPage param to force cache refreshing

546 of 4776 branches covered (11.43%)

Branch coverage included in aggregate %.

1401 of 8823 relevant lines covered (15.88%)

0.71 hits per line

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

0.0
src/main/java/com/knowledgepixels/nanodash/page/SpacePage.java
1
package com.knowledgepixels.nanodash.page;
2

3
import com.knowledgepixels.nanodash.*;
4
import com.knowledgepixels.nanodash.component.*;
5
import com.knowledgepixels.nanodash.connector.ConnectorConfig;
6
import com.knowledgepixels.nanodash.connector.GenOverviewPage;
7
import org.apache.wicket.Component;
8
import org.apache.wicket.RestartResponseException;
9
import org.apache.wicket.extensions.ajax.markup.html.AjaxLazyLoadPanel;
10
import org.apache.wicket.markup.html.basic.Label;
11
import org.apache.wicket.markup.html.link.AbstractLink;
12
import org.apache.wicket.markup.html.link.BookmarkablePageLink;
13
import org.apache.wicket.model.Model;
14
import org.apache.wicket.request.mapper.parameter.PageParameters;
15
import org.eclipse.rdf4j.model.IRI;
16
import org.nanopub.Nanopub;
17
import org.nanopub.extra.services.FailedApiCallException;
18
import org.nanopub.extra.services.QueryRef;
19

20
import java.time.LocalDateTime;
21
import java.time.ZoneId;
22
import java.time.format.DateTimeFormatter;
23
import java.util.ArrayList;
24
import java.util.List;
25

26
/**
27
 * The ProjectPage class represents a space page in the Nanodash application.
28
 */
29
public class SpacePage extends NanodashPage {
30

31
    /**
32
     * The mount path for this page.
33
     */
34
    public static final String MOUNT_PATH = "/space";
35

36
    /**
37
     * {@inheritDoc}
38
     */
39
    @Override
40
    public String getMountPath() {
41
        return MOUNT_PATH;
×
42
    }
43

44
    /**
45
     * Space object with the data shown on this page.
46
     */
47
    private Space space;
48

49
    private static final DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
×
50

51
    /**
52
     * Constructor for the SpacePage.
53
     *
54
     * @param parameters the page parameters
55
     * @throws org.nanopub.extra.services.FailedApiCallException if the API call fails
56
     */
57
    public SpacePage(final PageParameters parameters) throws FailedApiCallException {
58
        super(parameters);
×
59

60
        String id = parameters.get("id").toString();
×
61
        space = Space.get(id);
×
62
        if (space == null && MaintainedResource.get(id) != null) {
×
63
            throw new RestartResponseException(MaintainedResourcePage.class, parameters);
×
64
        }
65
        Nanopub np = space.getRootNanopub();
×
66

67
        add(new TitleBar("titlebar", this, "connectors"));
×
68

69
        add(new Label("pagetitle", space.getLabel() + " (space) | nanodash"));
×
70
        add(new Label("spacename", space.getLabel()));
×
71
        add(new Label("spacetype", space.getTypeLabel()));
×
72
        add(new BookmarkablePageLink<Void>("id", ExplorePage.class, parameters.set("label", space.getLabel())).setBody(Model.of(space.getId())));
×
73
        add(new BookmarkablePageLink<Void>("np", ExplorePage.class, new PageParameters().set("id", np.getUri())));
×
74

75
        add(new ItemListPanel<String>(
×
76
                "altids",
77
                "Alternative IDs:",
78
                space.getAltIDs(),
×
79
                i -> new ItemListElement("item", ExplorePage.class, new PageParameters().set("id", i), i)
×
80
            ));
81

82
        if (space.getStartDate() != null) {
×
83
            String dateString;
84
            LocalDateTime dt = LocalDateTime.ofInstant(space.getStartDate().toInstant(), ZoneId.systemDefault());
×
85
            dateString = dateTimeFormatter.format(dt);
×
86
            if (space.getEndDate() != null) {
×
87
                dt = LocalDateTime.ofInstant(space.getEndDate().toInstant(), ZoneId.systemDefault());
×
88
                String endDate = dateTimeFormatter.format(dt);
×
89
                if (!dateString.equals(endDate)) {
×
90
                    dateString += " - " + endDate;
×
91
                }
92
            }
93
            add(new Label("date", dateString));
×
94
        } else {
×
95
            add(new Label("date").setVisible(false));
×
96
        }
97

98
        add(new Label("description", "<span>" + Utils.sanitizeHtml(space.getDescription()) + "</span>").setEscapeModelStrings(false));
×
99

100
        final List<AbstractLink> pinButtons = new ArrayList<>();
×
101

102
        AbstractLink addPinnedTemplateButton = new BookmarkablePageLink<NanodashPage>("button", PublishPage.class, new PageParameters()
×
103
                .set("template", "https://w3id.org/np/RA2YwreWrGW9HkzWls8jgwaIINKUB5ZTli1aFKQt13dUk")
×
104
                .set("template-version", "latest")
×
105
                .set("param_space", space.getId())
×
106
                .set("context", space.getId())
×
107
        );
108
        addPinnedTemplateButton.setBody(Model.of("+ template"));
×
109
        pinButtons.add(addPinnedTemplateButton);
×
110

111
        AbstractLink addPinnedQueryButton = new BookmarkablePageLink<NanodashPage>("button", PublishPage.class, new PageParameters()
×
112
                .set("template", "https://w3id.org/np/RAuLESdeRUlk1GcTwvzVXShiBMI0ntJs2DL2Bm5DzW_ZQ")
×
113
                .set("template-version", "latest")
×
114
                .set("param_space", space.getId())
×
115
        );
116
        addPinnedQueryButton.setBody(Model.of("+ query"));
×
117
        pinButtons.add(addPinnedQueryButton);
×
118

119
        if (space.isDataInitialized()) {
×
120
            add(new PinGroupList("pin-groups", space));
×
121
            add(new ButtonList("pin-buttons", space, null, null, pinButtons));
×
122
        } else {
123
            add(new AjaxLazyLoadPanel<Component>("pin-groups") {
×
124

125
                @Override
126
                public Component getLazyLoadComponent(String markupId) {
127
                    return new PinGroupList(markupId, space);
×
128
                }
129

130
                @Override
131
                protected boolean isContentReady() {
132
                    return space.isDataInitialized();
×
133
                }
134

135
            });
136
            add(new AjaxLazyLoadPanel<Component>("pin-buttons") {
×
137

138
                @Override
139
                public Component getLazyLoadComponent(String markupId) {
140
                    return new ButtonList(markupId, space, null, null, pinButtons);
×
141
                }
142

143
                @Override
144
                protected boolean isContentReady() {
145
                    return space.isDataInitialized();
×
146
                }
147

148
                public Component getLoadingComponent(String id) {
149
                    return new Label(id).setVisible(false);
×
150
                }
151

152
            });
153
        }
154

155
        final List<AbstractLink> viewButtons = new ArrayList<>();
×
156
        AbstractLink addViewButton = new BookmarkablePageLink<NanodashPage>("button", PublishPage.class, new PageParameters()
×
157
                .set("template", "https://w3id.org/np/RAxERE0cQ9jLQZ5VjeA-1v3XnE9ugxLpFG8vpkAd5FqHE")
×
158
                .set("template-version", "latest")
×
159
                .set("param_resource", space.getId())
×
160
                .set("context", space.getId())
×
161
        );
162
        addViewButton.setBody(Model.of("+ view"));
×
163
        viewButtons.add(addViewButton);
×
164

165
        if (space.isDataInitialized()) {
×
166
            add(new ViewList("views", space));
×
167
            add(new ButtonList("view-buttons", space, null, null, viewButtons));
×
168
        } else {
169
            add(new AjaxLazyLoadPanel<Component>("views") {
×
170

171
                @Override
172
                public Component getLazyLoadComponent(String markupId) {
173
                    return new ViewList(markupId, space);
×
174
                }
175

176
                @Override
177
                protected boolean isContentReady() {
178
                    return space.isDataInitialized();
×
179
                }
180

181
            });
182
            add(new AjaxLazyLoadPanel<Component>("view-buttons") {
×
183

184
                @Override
185
                public Component getLazyLoadComponent(String markupId) {
186
                    return new ButtonList(markupId, space, null, null, viewButtons);
×
187
                }
188

189
                @Override
190
                protected boolean isContentReady() {
191
                    return space.isDataInitialized();
×
192
                }
193

194
                public Component getLoadingComponent(String id) {
195
                    return new Label(id).setVisible(false);
×
196
                }
197

198
                ;
199

200
            });
201
        }
202

203
        add(new ItemListPanel<>(
×
204
                        "roles",
205
                        "Roles:",
206
                        () -> space.isDataInitialized(),
×
207
                        () -> space.getRoles(),
×
208
                        r -> new ItemListElement("item", ExplorePage.class, new PageParameters().set("id", r.getId()), r.getName())
×
209
                )
210
                        .makeInline()
×
211
                        .setSpace(space)
×
212
                        .addAdminButton("+", PublishPage.class, new PageParameters()
×
213
                                .set("template", "https://w3id.org/np/RARBzGkEqiQzeiHk0EXFcv9Ol1d-17iOh9MoFJzgfVQDc")
×
214
                                .set("param_space", space.getId())
×
215
                                .set("refresh-upon-publish", space.getId())
×
216
                                .set("template-version", "latest")
×
217
                        )
218
        );
219

220
        add(new ItemListPanel<IRI>(
×
221
                "users",
222
                "Users",
223
                () -> space.isDataInitialized(),
×
224
                () -> space.getUsers(),
×
225
                m -> {
226
                    String roleLabel = "(";
×
227
                    for (SpaceMemberRole r : space.getMemberRoles(m)) {
×
228
                        roleLabel += r.getName() + ", ";
×
229
                    }
×
230
                    roleLabel = roleLabel.replaceFirst(", $", ")");
×
231
                    return new ItemListElement("item", UserPage.class, new PageParameters().set("id", m), User.getShortDisplayName(m), roleLabel, null);
×
232
                }
233
        ));
234

235

236
        if (space.isDataInitialized()) {
×
237
            add(new SpaceUserList("user-lists", space));
×
238
        } else {
239
            add(new AjaxLazyLoadPanel<Component>("user-lists") {
×
240

241
                @Override
242
                public Component getLazyLoadComponent(String markupId) {
243
                    return new SpaceUserList(markupId, space);
×
244
                }
245

246
                @Override
247
                protected boolean isContentReady() {
248
                    return space.isDataInitialized();
×
249
                }
250

251
            });
252
        }
253

254
        add(new ItemListPanel<Space>(
×
255
                "superspaces",
256
                "Part of",
257
                space.getSuperspaces(),
×
258
                (space) -> new ItemListElement("item", SpacePage.class, new PageParameters().set("id", space), space.getLabel(), "(" + space.getTypeLabel() + ")", null)
×
259
        ));
260

261
        addSubspacePanel("Alliance", true);
×
262
        addSubspacePanel("Consortium", false);
×
263
        addSubspacePanel("Organization", true);
×
264
        addSubspacePanel("Taskforce", false);
×
265
        addSubspacePanel("Division", true);
×
266
        addSubspacePanel("Taskunit", false);
×
267
        addSubspacePanel("Group", true);
×
268
        addSubspacePanel("Project", false);
×
269
        addSubspacePanel("Program", true);
×
270
        addSubspacePanel("Initiative", false);
×
271
        addSubspacePanel("Outlet", true);
×
272
        addSubspacePanel("Campaign", false);
×
273
        addSubspacePanel("Community", true);
×
274
        addSubspacePanel("Event", false);
×
275

276
        add(new ItemListPanel<MaintainedResource>(
×
277
                "resources",
278
                "Resources",
279
                new QueryRef("get-maintained-resources"),
280
                (apiResponse) -> {
281
                    MaintainedResource.ensureLoaded();
×
282
                    return MaintainedResource.getResourcesBySpace(space);
×
283
                },
284
                (resource) -> {
285
                    return new ItemListElement("item", MaintainedResourcePage.class, new PageParameters().set("id", resource.getId()), resource.getLabel());
×
286
                }
287
        )
288
                .setSpace(space)
×
289
                .setReadyFunction(space::isDataInitialized)
×
290
                .addMemberButton("+", PublishPage.class, new PageParameters()
×
291
                        .set("template", "https://w3id.org/np/RA25VaVFxSOgKEuZ70gFINn-N3QV4Pf62-IMK_SWkg-c8")
×
292
                        .set("param_space", space.getId())
×
293
                        .set("context", space.getId())
×
294
                        .set("refresh-upon-publish", "maintainedResources")
×
295
                        .set("template-version", "latest")
×
296
                ));
297

298
        String shortId = space.getId().replace("https://w3id.org/spaces/", "");
×
299
        ConnectorConfig cc = ConnectorConfig.get(shortId);
×
300
        if (cc != null) {
×
301
            add(new BookmarkablePageLink<Void>("content-button", GenOverviewPage.class, new PageParameters().set("journal", shortId)).setBody(Model.of("Nanopublication Submissions")));
×
302
        } else {
303
            add(new Label("content-button").setVisible(false));
×
304
        }
305
    }
×
306

307
    private void addSubspacePanel(String type, boolean openEnded) {
308
        String typePl = type + "s";
×
309
        typePl = typePl.replaceFirst("ys$", "ies");
×
310

311
        add(new ItemListPanel<>(
×
312
                        typePl.toLowerCase(),
×
313
                        typePl,
314
                        space.getSubspaces("https://w3id.org/kpxl/gen/terms/" + type),
×
315
                        (space) -> new ItemListElement("item", SpacePage.class, new PageParameters().set("id", space), space.getLabel())
×
316
                )
317
                        .setSpace(space)
×
318
                        .setReadyFunction(space::isDataInitialized)
×
319
                        .addMemberButton("+", PublishPage.class, new PageParameters()
×
320
                                .set("template", openEnded ? "https://w3id.org/np/RA7dQfmndqKmooQ4PlHyQsAql9i2tg_8GLHf_dqtxsGEQ" : "https://w3id.org/np/RAaE7NP9RNIx03AHZxanFMdtUuaTfe50ns5tHhpEVloQ4")
×
321
                                .set("param_type", "https://w3id.org/kpxl/gen/terms/" + type)
×
322
                                .set("param_space", space.getId().replaceFirst("https://w3id.org/spaces/", "") + "/<SET-SUFFIX>")
×
323
                                .set("refresh-upon-publish", "spaces")
×
324
                                .set("template-version", "latest"))
×
325
        );
326
    }
×
327

328
    /**
329
     * Checks if auto-refresh is enabled for this page.
330
     *
331
     * @return true if auto-refresh is enabled, false otherwise
332
     */
333
    protected boolean hasAutoRefreshEnabled() {
334
        return true;
×
335
    }
336

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