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

knowledgepixels / nanodash / 21596202545

02 Feb 2026 03:29PM UTC coverage: 14.306% (+0.02%) from 14.286%
21596202545

push

github

web-flow
Merge pull request #349 from knowledgepixels/343-domain-model-refactor

Domain model refactor to avoid confusion around different meanings

570 of 5258 branches covered (10.84%)

Branch coverage included in aggregate %.

1554 of 9589 relevant lines covered (16.21%)

2.1 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/ResourcePartPage.java
1
package com.knowledgepixels.nanodash.page;
2

3
import com.knowledgepixels.nanodash.*;
4
import com.knowledgepixels.nanodash.component.ButtonList;
5
import com.knowledgepixels.nanodash.component.TitleBar;
6
import com.knowledgepixels.nanodash.component.ViewList;
7
import org.apache.wicket.Component;
8
import org.apache.wicket.extensions.ajax.markup.html.AjaxLazyLoadPanel;
9
import org.apache.wicket.markup.html.basic.Label;
10
import org.apache.wicket.markup.html.link.AbstractLink;
11
import org.apache.wicket.markup.html.link.BookmarkablePageLink;
12
import org.apache.wicket.model.Model;
13
import org.apache.wicket.request.mapper.parameter.PageParameters;
14
import org.eclipse.rdf4j.model.IRI;
15
import org.eclipse.rdf4j.model.Statement;
16
import org.eclipse.rdf4j.model.vocabulary.DCTERMS;
17
import org.eclipse.rdf4j.model.vocabulary.RDF;
18
import org.eclipse.rdf4j.model.vocabulary.RDFS;
19
import org.eclipse.rdf4j.model.vocabulary.SKOS;
20
import org.nanopub.Nanopub;
21
import org.nanopub.extra.services.ApiResponse;
22
import org.nanopub.extra.services.QueryRef;
23

24
import java.util.ArrayList;
25
import java.util.HashSet;
26
import java.util.List;
27
import java.util.Set;
28

29
/**
30
 * This class represents a page for a resource part in the context of a maintained resource, space, or user.
31
 */
32
public class ResourcePartPage extends NanodashPage {
33

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

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

47
    /**
48
     * Resource with profile (Space or MaintainedResource) object with the data shown on this page.
49
     */
50
    private ResourceWithProfile resourceWithProfile;
51

52
    public ResourcePartPage(final PageParameters parameters) {
53
        super(parameters);
×
54

55
        final String id = parameters.get("id").toString();
×
56
        final String contextId = parameters.get("context").toString();
×
57
        final String nanopubId;
58
        String label = id.replaceFirst("^.*[#/]([^#/]+)$", "$1");
×
59
        String description = null;
×
60
        Set<IRI> classes = new HashSet<>();
×
61

62
        resourceWithProfile = MaintainedResource.get(contextId);
×
63
        if (resourceWithProfile == null) {
×
64
            if (Space.get(contextId) != null) {
×
65
                resourceWithProfile = Space.get(contextId);
×
66
            } else if (User.isUser(contextId)) {
×
67
                resourceWithProfile = IndividualAgent.get(contextId);
×
68
            } else {
69
                throw new IllegalArgumentException("Not a resource, space, or user: " + contextId);
×
70
            }
71
        }
72

73
        QueryRef getDefQuery = new QueryRef("get-term-definitions", "term", id);
×
74
        if (resourceWithProfile.getSpace() != null) {
×
75
            for (IRI userIri : resourceWithProfile.getSpace().getUsers()) {
×
76
                for (String pubkey : User.getUserData().getPubkeyhashes(userIri, true)) {
×
77
                    getDefQuery.getParams().put("pubkey", pubkey);
×
78
                }
×
79
            }
×
80
        } else {
81
            for (String pubkey : User.getUserData().getPubkeyhashes(Utils.vf.createIRI(contextId), true)) {
×
82
                getDefQuery.getParams().put("pubkey", pubkey);
×
83
            }
×
84
        }
85

86
        ApiResponse getDefResp = ApiCache.retrieveResponseSync(getDefQuery, false);
×
87
        if (getDefResp != null && !getDefResp.getData().isEmpty()) {
×
88
            nanopubId = getDefResp.getData().iterator().next().get("np");
×
89

90
            Nanopub nanopub = Utils.getAsNanopub(nanopubId);
×
91
            for (Statement st : nanopub.getAssertion()) {
×
92
                if (!st.getSubject().stringValue().equals(id)) {
×
93
                    continue;
×
94
                }
95
                if (st.getPredicate().equals(RDFS.LABEL)) {
×
96
                    label = st.getObject().stringValue();
×
97
                }
98
                if (st.getPredicate().equals(SKOS.DEFINITION) || st.getPredicate().equals(DCTERMS.DESCRIPTION) || st.getPredicate().equals(RDFS.COMMENT)) {
×
99
                    description = st.getObject().stringValue();
×
100
                }
101
                if (st.getPredicate().equals(RDF.TYPE) && st.getObject() instanceof IRI objIri) {
×
102
                    classes.add(objIri);
×
103
                }
104
            }
×
105
        } else {
×
106
            nanopubId = null;
×
107
        }
108
//        if (getDefResp == null || getDefResp.getData().isEmpty()) {
109
//            throw new RestartResponseException(ExplorePage.class, parameters);
110
//        }
111

112
        if (description != null) {
×
113
            add(new Label("description", description));
×
114
        } else {
115
            add(new Label("description").setVisible(false));
×
116
        }
117

118
        List<NanodashPageRef> breadCrumb;
119
        if (resourceWithProfile.getSpace() != null) {
×
120
            List<ResourceWithProfile> superSpaces = resourceWithProfile.getSpace().getAllSuperSpacesUntilRoot();
×
121
            if (resourceWithProfile instanceof MaintainedResource) {
×
122
                superSpaces.add(resourceWithProfile.getSpace());
×
123
            }
124
            superSpaces.add(resourceWithProfile);
×
125
            breadCrumb = new ArrayList<>(superSpaces.stream().map(ss -> new NanodashPageRef(SpacePage.class, new PageParameters().add("id", ss.getId()), ss.getLabel())).toList());
×
126
        } else {
×
127
            breadCrumb = new ArrayList<>();
×
128
            breadCrumb.add(new NanodashPageRef(UserPage.class, new PageParameters().add("id", contextId), resourceWithProfile.getLabel()));
×
129
        }
130
        breadCrumb.add(new NanodashPageRef(ResourcePartPage.class, new PageParameters().add("id", id).add("context", contextId).add("label", label), label));
×
131
        NanodashPageRef[] breadCrumbArray = breadCrumb.toArray(new NanodashPageRef[0]);
×
132
        add(new TitleBar("titlebar", this, null,
×
133
                breadCrumbArray
134
        ));
135

136
        add(new Label("pagetitle", label + " (resource part) | nanodash"));
×
137
        add(new Label("name", label));
×
138
        add(new BookmarkablePageLink<Void>("id", ExplorePage.class, parameters.set("label", label)).setBody(Model.of(id)));
×
139
        add(new BookmarkablePageLink<Void>("np", ExplorePage.class, new PageParameters().set("id", nanopubId == null ? id : nanopubId)));
×
140

141
        // TODO Improve this code, e.g. make Space a subclass of MaintainedResource or otherwise refactor:
142
        // we now use the ProfileResource abstraction, but the code still has to be imprved
143
        if (resourceWithProfile != null) {
×
144
            final List<AbstractLink> viewButtons = new ArrayList<>();
×
145
            AbstractLink addViewButton = new BookmarkablePageLink<NanodashPage>("button", PublishPage.class, new PageParameters()
×
146
                    .set("template", "https://w3id.org/np/RAPxKWDTDP4neVtRckQcTqKHqCC_GHWWPrs7DESb2BJjo")
×
147
                    .set("template-version", "latest")
×
148
                    .set("param_resource", resourceWithProfile.getId())
×
149
                    .set("context", resourceWithProfile.getId())
×
150
                    .set("part", id)
×
151
            );
152
            addViewButton.setBody(Model.of("+ view"));
×
153
            viewButtons.add(addViewButton);
×
154

155
            final String nanopubRef = nanopubId == null ? "x:" : nanopubId;
×
156
            if (resourceWithProfile.isDataInitialized()) {
×
157
                add(new ViewList("views", resourceWithProfile, id, nanopubRef, classes));
×
158
                add(new ButtonList("view-buttons", resourceWithProfile.getSpace() != null ? resourceWithProfile.getSpace() : resourceWithProfile, null, null, viewButtons));
×
159
            } else {
160
                add(new AjaxLazyLoadPanel<Component>("views") {
×
161

162
                    @Override
163
                    public Component getLazyLoadComponent(String markupId) {
164
                        return new ViewList(markupId, resourceWithProfile, id, nanopubRef, classes);
×
165
                    }
166

167
                    @Override
168
                    protected boolean isContentReady() {
169
                        return resourceWithProfile.isDataInitialized();
×
170
                    }
171

172
                });
173
                add(new AjaxLazyLoadPanel<Component>("view-buttons") {
×
174

175
                    @Override
176
                    public Component getLazyLoadComponent(String markupId) {
177
                        return new ButtonList(markupId, resourceWithProfile.getSpace() != null ? resourceWithProfile.getSpace() : resourceWithProfile, null, null, viewButtons);
×
178
                    }
179

180
                    @Override
181
                    protected boolean isContentReady() {
182
                        return resourceWithProfile.isDataInitialized();
×
183
                    }
184

185
                    public Component getLoadingComponent(String id) {
186
                        return new Label(id).setVisible(false);
×
187
                    }
188

189
                });
190
            }
191
        } else {
×
192
            // TODO Ugly code duplication (see above):
193

194
            final List<AbstractLink> viewButtons = new ArrayList<>();
×
195
            AbstractLink addViewButton = new BookmarkablePageLink<NanodashPage>("button", PublishPage.class, new PageParameters()
×
196
                    .set("template", "https://w3id.org/np/RAPxKWDTDP4neVtRckQcTqKHqCC_GHWWPrs7DESb2BJjo")
×
197
                    .set("template-version", "latest")
×
198
                    .set("param_resource", resourceWithProfile.getSpace().getId())
×
199
                    .set("context", resourceWithProfile.getSpace().getId())
×
200
                    .set("part", id)
×
201
            );
202
            addViewButton.setBody(Model.of("+ view"));
×
203
            viewButtons.add(addViewButton);
×
204

205
            if (resourceWithProfile.getSpace().isDataInitialized()) {
×
206
                add(new ViewList("views", resourceWithProfile.getSpace(), id, nanopubId, classes));
×
207
                add(new ButtonList("view-buttons", resourceWithProfile.getSpace(), null, null, viewButtons));
×
208
            } else {
209
                add(new AjaxLazyLoadPanel<Component>("views") {
×
210

211
                    @Override
212
                    public Component getLazyLoadComponent(String markupId) {
213
                        return new ViewList(markupId, resourceWithProfile.getSpace(), id, nanopubId, classes);
×
214
                    }
215

216
                    @Override
217
                    protected boolean isContentReady() {
218
                        return resourceWithProfile.getSpace().isDataInitialized();
×
219
                    }
220

221
                });
222
                add(new AjaxLazyLoadPanel<Component>("view-buttons") {
×
223

224
                    @Override
225
                    public Component getLazyLoadComponent(String markupId) {
226
                        return new ButtonList(markupId, resourceWithProfile.getSpace(), null, null, viewButtons);
×
227
                    }
228

229
                    @Override
230
                    protected boolean isContentReady() {
231
                        return resourceWithProfile.getSpace().isDataInitialized();
×
232
                    }
233

234
                    public Component getLoadingComponent(String id) {
235
                        return new Label(id).setVisible(false);
×
236
                    }
237

238
                });
239
            }
240
        }
241
    }
×
242

243
    /**
244
     * Checks if auto-refresh is enabled for this page.
245
     *
246
     * @return true if auto-refresh is enabled, false otherwise
247
     */
248
    protected boolean hasAutoRefreshEnabled() {
249
        return true;
×
250
    }
251

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