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

knowledgepixels / nanodash / 19820983664

01 Dec 2025 11:24AM UTC coverage: 15.298% (+1.9%) from 13.36%
19820983664

push

github

web-flow
Merge pull request #313 from knowledgepixels/296-refactor-usage-of-pair-as-classes

Replace Pair with new class

591 of 4966 branches covered (11.9%)

Branch coverage included in aggregate %.

1559 of 9088 relevant lines covered (17.15%)

0.76 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.MaintainedResource;
4
import com.knowledgepixels.nanodash.Space;
5
import com.knowledgepixels.nanodash.Utils;
6
import com.knowledgepixels.nanodash.component.*;
7
import com.knowledgepixels.nanodash.connector.ConnectorConfig;
8
import com.knowledgepixels.nanodash.connector.GenOverviewPage;
9
import com.knowledgepixels.nanodash.vocabulary.KPXL_TERMS;
10
import org.apache.wicket.Component;
11
import org.apache.wicket.RestartResponseException;
12
import org.apache.wicket.extensions.ajax.markup.html.AjaxLazyLoadPanel;
13
import org.apache.wicket.markup.html.basic.Label;
14
import org.apache.wicket.markup.html.link.AbstractLink;
15
import org.apache.wicket.markup.html.link.BookmarkablePageLink;
16
import org.apache.wicket.model.Model;
17
import org.apache.wicket.request.mapper.parameter.PageParameters;
18
import org.nanopub.Nanopub;
19
import org.nanopub.extra.services.FailedApiCallException;
20
import org.nanopub.extra.services.QueryRef;
21

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

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

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

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

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

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

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

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

69
        add(new TitleBar("titlebar", this, "connectors"));
×
70

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

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

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

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

102
        final List<AbstractLink> pinButtons = new ArrayList<>();
×
103

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

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

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

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

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

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

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

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

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

154
            });
155
        }
156

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

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

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

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

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

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

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

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

200
                ;
201

202
            });
203
        }
204

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

222
        if (space.isDataInitialized()) {
×
223
            add(new SpaceUserList("user-lists", space));
×
224
        } else {
225
            add(new AjaxLazyLoadPanel<Component>("user-lists") {
×
226

227
                @Override
228
                public Component getLazyLoadComponent(String markupId) {
229
                    return new SpaceUserList(markupId, space);
×
230
                }
231

232
                @Override
233
                protected boolean isContentReady() {
234
                    return space.isDataInitialized();
×
235
                }
236

237
            });
238
        }
239

240
        add(new ItemListPanel<Space>(
×
241
                "superspaces",
242
                "Part of",
243
                space.getSuperspaces(),
×
244
                (space) -> new ItemListElement("item", SpacePage.class, new PageParameters().set("id", space), space.getLabel(), "(" + space.getTypeLabel() + ")", null)
×
245
        ));
246

247
        addSubspacePanel("Alliance", true);
×
248
        addSubspacePanel("Consortium", false);
×
249
        addSubspacePanel("Organization", true);
×
250
        addSubspacePanel("Taskforce", false);
×
251
        addSubspacePanel("Division", true);
×
252
        addSubspacePanel("Taskunit", false);
×
253
        addSubspacePanel("Group", true);
×
254
        addSubspacePanel("Project", false);
×
255
        addSubspacePanel("Program", true);
×
256
        addSubspacePanel("Initiative", false);
×
257
        addSubspacePanel("Outlet", true);
×
258
        addSubspacePanel("Campaign", false);
×
259
        addSubspacePanel("Community", true);
×
260
        addSubspacePanel("Event", false);
×
261

262
        add(new ItemListPanel<MaintainedResource>(
×
263
                "resources",
264
                "Resources",
265
                new QueryRef("get-maintained-resources"),
266
                (apiResponse) -> {
267
                    MaintainedResource.ensureLoaded();
×
268
                    return MaintainedResource.getResourcesBySpace(space);
×
269
                },
270
                (resource) -> {
271
                    return new ItemListElement("item", MaintainedResourcePage.class, new PageParameters().set("id", resource.getId()), resource.getLabel());
×
272
                }
273
        )
274
                .setProfiledResource(space)
×
275
                .setReadyFunction(space::isDataInitialized)
×
276
                .addMemberButton("+", PublishPage.class, new PageParameters()
×
277
                        .set("template", "https://w3id.org/np/RA25VaVFxSOgKEuZ70gFINn-N3QV4Pf62-IMK_SWkg-c8")
×
278
                        .set("param_space", space.getId())
×
279
                        .set("context", space.getId())
×
280
                        .set("refresh-upon-publish", "maintainedResources")
×
281
                        .set("template-version", "latest")
×
282
                ));
283

284
        String shortId = space.getId().replace("https://w3id.org/spaces/", "");
×
285
        ConnectorConfig cc = ConnectorConfig.get(shortId);
×
286
        if (cc != null) {
×
287
            add(new BookmarkablePageLink<Void>("content-button", GenOverviewPage.class, new PageParameters().set("journal", shortId)).setBody(Model.of("Nanopublication Submissions")));
×
288
        } else {
289
            add(new Label("content-button").setVisible(false));
×
290
        }
291
    }
×
292

293
    private void addSubspacePanel(String type, boolean openEnded) {
294
        String typePl = type + "s";
×
295
        typePl = typePl.replaceFirst("ys$", "ies");
×
296

297
        add(new ItemListPanel<>(
×
298
                        typePl.toLowerCase(),
×
299
                        typePl,
300
                        space.getSubspaces(KPXL_TERMS.NAMESPACE + type),
×
301
                        (space) -> new ItemListElement("item", SpacePage.class, new PageParameters().set("id", space), space.getLabel())
×
302
                )
303
                        .setProfiledResource(space)
×
304
                        .setReadyFunction(space::isDataInitialized)
×
305
                        .addMemberButton("+", PublishPage.class, new PageParameters()
×
306
                                .set("template", openEnded ? "https://w3id.org/np/RA7dQfmndqKmooQ4PlHyQsAql9i2tg_8GLHf_dqtxsGEQ" : "https://w3id.org/np/RAaE7NP9RNIx03AHZxanFMdtUuaTfe50ns5tHhpEVloQ4")
×
307
                                .set("param_type", KPXL_TERMS.NAMESPACE + type)
×
308
                                .set("param_space", space.getId().replaceFirst("https://w3id.org/spaces/", "") + "/<SET-SUFFIX>")
×
309
                                .set("refresh-upon-publish", "spaces")
×
310
                                .set("template-version", "latest"))
×
311
        );
312
    }
×
313

314
    /**
315
     * Checks if auto-refresh is enabled for this page.
316
     *
317
     * @return true if auto-refresh is enabled, false otherwise
318
     */
319
    protected boolean hasAutoRefreshEnabled() {
320
        return true;
×
321
    }
322

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