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

knowledgepixels / nanodash / 20299457275

17 Dec 2025 10:20AM UTC coverage: 14.401% (-0.9%) from 15.279%
20299457275

push

github

tkuhn
fix: Use API result cache for all requests

546 of 5004 branches covered (10.91%)

Branch coverage included in aggregate %.

1496 of 9176 relevant lines covered (16.3%)

2.13 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 java.util.ArrayList;
4
import java.util.HashSet;
5
import java.util.List;
6
import java.util.Set;
7

8
import org.apache.wicket.Component;
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.eclipse.rdf4j.model.Statement;
17
import org.eclipse.rdf4j.model.vocabulary.DCTERMS;
18
import org.eclipse.rdf4j.model.vocabulary.RDF;
19
import org.eclipse.rdf4j.model.vocabulary.RDFS;
20
import org.eclipse.rdf4j.model.vocabulary.SKOS;
21
import org.nanopub.Nanopub;
22
import org.nanopub.extra.services.ApiResponse;
23
import org.nanopub.extra.services.QueryRef;
24

25
import com.knowledgepixels.nanodash.ApiCache;
26
import com.knowledgepixels.nanodash.MaintainedResource;
27
import com.knowledgepixels.nanodash.NanodashPageRef;
28
import com.knowledgepixels.nanodash.ProfiledResource;
29
import com.knowledgepixels.nanodash.Space;
30
import com.knowledgepixels.nanodash.User;
31
import com.knowledgepixels.nanodash.Utils;
32
import com.knowledgepixels.nanodash.component.ButtonList;
33
import com.knowledgepixels.nanodash.component.TitleBar;
34
import com.knowledgepixels.nanodash.component.ViewList;
35

36
/**
37
 * This class represents a page for a maintained resource.
38
 */
39
public class ResourcePartPage extends NanodashPage {
40

41
    /**
42
     * The mount path for this page.
43
     */
44
    public static final String MOUNT_PATH = "/part";
45

46
    /**
47
     * {@inheritDoc}
48
     */
49
    @Override
50
    public String getMountPath() {
51
        return MOUNT_PATH;
×
52
    }
53

54
    /**
55
     * Profiled resource (Space or MaintainedResource) object with the data shown on this page.
56
     */
57
    private ProfiledResource profiledResource;
58

59
    public ResourcePartPage(final PageParameters parameters) {
60
        super(parameters);
×
61

62
        final String id = parameters.get("id").toString();
×
63
        final String contextId = parameters.get("context").toString();
×
64
        final String nanopubId;
65
        String label = id.replaceFirst("^.*[#/]([^#/]+)$", "$1");
×
66
        String description = null;
×
67
        Set<IRI> classes = new HashSet<>();
×
68

69
        profiledResource = MaintainedResource.get(contextId);
×
70
        if (profiledResource == null) {
×
71
            if (Space.get(contextId) == null) {
×
72
                throw new IllegalArgumentException("Not a resource or space: " + contextId);
×
73
            }
74
            profiledResource = Space.get(contextId);
×
75
        }
76

77
        QueryRef getDefQuery = new QueryRef("get-term-definitions", "term", id);
×
78
        for (IRI userIri : profiledResource.getSpace().getUsers()) {
×
79
            for (String pubkey : User.getUserData().getPubkeyhashes(userIri, true)) {
×
80
                getDefQuery.getParams().put("pubkey", pubkey);
×
81
            }
×
82
        }
×
83

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

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

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

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

131
        add(new Label("pagetitle", label + " (resource part) | nanodash"));
×
132
        add(new Label("name", label));
×
133
        add(new BookmarkablePageLink<Void>("id", ExplorePage.class, parameters.set("label", label)).setBody(Model.of(id)));
×
134
        add(new BookmarkablePageLink<Void>("np", ExplorePage.class, new PageParameters().set("id", nanopubId == null ? id : nanopubId)));
×
135

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

149
            final String nanopubRef = nanopubId == null ? "x:" : nanopubId;
×
150
            if (profiledResource.isDataInitialized()) {
×
151
                add(new ViewList("views", profiledResource, id, nanopubRef, classes));
×
152
                add(new ButtonList("view-buttons", profiledResource.getSpace(), null, null, viewButtons));
×
153
            } else {
154
                add(new AjaxLazyLoadPanel<Component>("views") {
×
155

156
                    @Override
157
                    public Component getLazyLoadComponent(String markupId) {
158
                        return new ViewList(markupId, profiledResource, id, nanopubRef, classes);
×
159
                    }
160

161
                    @Override
162
                    protected boolean isContentReady() {
163
                        return profiledResource.isDataInitialized();
×
164
                    }
165

166
                });
167
                add(new AjaxLazyLoadPanel<Component>("view-buttons") {
×
168

169
                    @Override
170
                    public Component getLazyLoadComponent(String markupId) {
171
                        return new ButtonList(markupId, profiledResource.getSpace(), null, null, viewButtons);
×
172
                    }
173

174
                    @Override
175
                    protected boolean isContentReady() {
176
                        return profiledResource.isDataInitialized();
×
177
                    }
178

179
                    public Component getLoadingComponent(String id) {
180
                        return new Label(id).setVisible(false);
×
181
                    }
182

183
                });
184
            }
185
        } else {
×
186
            // TODO Ugly code duplication (see above):
187

188
            final List<AbstractLink> viewButtons = new ArrayList<>();
×
189
            AbstractLink addViewButton = new BookmarkablePageLink<NanodashPage>("button", PublishPage.class, new PageParameters()
×
190
                    .set("template", "https://w3id.org/np/RAPxKWDTDP4neVtRckQcTqKHqCC_GHWWPrs7DESb2BJjo")
×
191
                    .set("template-version", "latest")
×
192
                    .set("param_resource", profiledResource.getSpace().getId())
×
193
                    .set("context", profiledResource.getSpace().getId())
×
194
            );
195
            addViewButton.setBody(Model.of("+ view"));
×
196
            viewButtons.add(addViewButton);
×
197

198
            if (profiledResource.getSpace().isDataInitialized()) {
×
199
                add(new ViewList("views", profiledResource.getSpace(), id, nanopubId, classes));
×
200
                add(new ButtonList("view-buttons", profiledResource.getSpace(), null, null, viewButtons));
×
201
            } else {
202
                add(new AjaxLazyLoadPanel<Component>("views") {
×
203

204
                    @Override
205
                    public Component getLazyLoadComponent(String markupId) {
206
                        return new ViewList(markupId, profiledResource.getSpace(), id, nanopubId, classes);
×
207
                    }
208

209
                    @Override
210
                    protected boolean isContentReady() {
211
                        return profiledResource.getSpace().isDataInitialized();
×
212
                    }
213

214
                });
215
                add(new AjaxLazyLoadPanel<Component>("view-buttons") {
×
216

217
                    @Override
218
                    public Component getLazyLoadComponent(String markupId) {
219
                        return new ButtonList(markupId, profiledResource.getSpace(), null, null, viewButtons);
×
220
                    }
221

222
                    @Override
223
                    protected boolean isContentReady() {
224
                        return profiledResource.getSpace().isDataInitialized();
×
225
                    }
226

227
                    public Component getLoadingComponent(String id) {
228
                        return new Label(id).setVisible(false);
×
229
                    }
230

231
                });
232
            }
233
        }
234
    }
×
235

236
    /**
237
     * Checks if auto-refresh is enabled for this page.
238
     *
239
     * @return true if auto-refresh is enabled, false otherwise
240
     */
241
    protected boolean hasAutoRefreshEnabled() {
242
        return true;
×
243
    }
244

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