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

knowledgepixels / nanodash / 27831881428

19 Jun 2026 02:34PM UTC coverage: 26.652% (+0.07%) from 26.583%
27831881428

push

github

web-flow
Merge pull request #489 from knowledgepixels/feat/per-type-preset-templates

feat: per-type "add preset" templates (type-filtered preset choice)

1553 of 6847 branches covered (22.68%)

Branch coverage included in aggregate %.

3421 of 11816 relevant lines covered (28.95%)

4.26 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.ApiCache;
4
import com.knowledgepixels.nanodash.NanodashPageRef;
5
import com.knowledgepixels.nanodash.QueryApiAccess;
6
import com.knowledgepixels.nanodash.Utils;
7
import com.knowledgepixels.nanodash.component.*;
8
import com.knowledgepixels.nanodash.domain.AbstractResourceWithProfile;
9
import com.knowledgepixels.nanodash.domain.IndividualAgent;
10
import com.knowledgepixels.nanodash.domain.MaintainedResource;
11
import com.knowledgepixels.nanodash.domain.User;
12
import com.knowledgepixels.nanodash.repository.MaintainedResourceRepository;
13
import com.knowledgepixels.nanodash.repository.SpaceRepository;
14
import org.apache.wicket.Component;
15
import org.apache.wicket.extensions.ajax.markup.html.AjaxLazyLoadPanel;
16
import org.apache.wicket.markup.html.WebMarkupContainer;
17
import org.apache.wicket.markup.html.basic.Label;
18
import org.apache.wicket.markup.html.panel.EmptyPanel;
19
import org.apache.wicket.model.Model;
20
import org.apache.wicket.request.mapper.parameter.PageParameters;
21
import org.eclipse.rdf4j.model.IRI;
22
import org.eclipse.rdf4j.model.Statement;
23
import org.eclipse.rdf4j.model.util.Values;
24
import org.eclipse.rdf4j.model.vocabulary.RDF;
25
import org.eclipse.rdf4j.model.vocabulary.RDFS;
26
import org.nanopub.Nanopub;
27
import org.nanopub.extra.services.ApiResponse;
28
import org.nanopub.extra.services.QueryRef;
29

30
import java.util.ArrayList;
31
import java.util.HashSet;
32
import java.util.List;
33
import java.util.Set;
34

35
/**
36
 * This class represents a page for a resource part in the context of a maintained resource, space, or user.
37
 */
38
public class ResourcePartPage extends NanodashPage {
39

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

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

53
    /**
54
     * Resource with profile (Space or MaintainedResource) object with the data shown on this page.
55
     */
56
    private AbstractResourceWithProfile resourceWithProfile;
57

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

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

67
        resourceWithProfile = MaintainedResourceRepository.get().findById(contextId);
×
68
        if (resourceWithProfile == null) {
×
69
            if (SpaceRepository.get().findById(contextId) != null) {
×
70
                resourceWithProfile = SpaceRepository.get().findById(contextId);
×
71
            } else if (IndividualAgent.isUser(contextId)) {
×
72
                resourceWithProfile = IndividualAgent.get(contextId);
×
73
            } else {
74
                throw new IllegalArgumentException("Not a resource, space, or user: " + contextId);
×
75
            }
76
        }
77

78
        QueryRef getDefQuery = new QueryRef(QueryApiAccess.GET_TERM_DEFINITIONS, "term", id);
×
79
        if (resourceWithProfile.getSpace() != null) {
×
80
            for (IRI userIri : resourceWithProfile.getSpace().getUsers()) {
×
81
                for (String pubkey : User.getUserData().getPubkeyHashes(userIri, true)) {
×
82
                    getDefQuery.getParams().put("pubkey", pubkey);
×
83
                }
×
84
            }
×
85
        } else {
86
            for (String pubkey : User.getUserData().getPubkeyHashes(Utils.vf.createIRI(contextId), true)) {
×
87
                getDefQuery.getParams().put("pubkey", pubkey);
×
88
            }
×
89
        }
90

91
        ApiResponse getDefResp = ApiCache.retrieveResponseSync(getDefQuery, false);
×
92
        if (getDefResp != null && !getDefResp.getData().isEmpty()) {
×
93
            nanopubId = getDefResp.getData().iterator().next().get("np");
×
94

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

114
        List<NanodashPageRef> breadCrumb;
115
        if (resourceWithProfile.getSpace() != null) {
×
116
            List<AbstractResourceWithProfile> superSpaces = resourceWithProfile.getSpace().getAllSuperSpacesUntilRoot();
×
117
            if (resourceWithProfile instanceof MaintainedResource) {
×
118
                superSpaces.add(resourceWithProfile.getSpace());
×
119
            }
120
            superSpaces.add(resourceWithProfile);
×
121
            breadCrumb = new ArrayList<>(superSpaces.stream().map(ss -> new NanodashPageRef(SpacePage.class, new PageParameters().add("id", ss.getId()), ss.getLabel())).toList());
×
122
        } else {
×
123
            breadCrumb = new ArrayList<>();
×
124
            breadCrumb.add(new NanodashPageRef(UserPage.class, new PageParameters().add("id", contextId), resourceWithProfile.getLabel()));
×
125
        }
126
        breadCrumb.add(new NanodashPageRef(ResourcePartPage.class, new PageParameters().add("id", id).add("context", contextId).add("label", label), label));
×
127
        NanodashPageRef[] breadCrumbArray = breadCrumb.toArray(new NanodashPageRef[0]);
×
128
        ResourceTabs.Tab activeTab = ResourceTabs.activeFromParam(parameters);
×
129
        add(new TitleBar("titlebar", this, null,
×
130
                breadCrumbArray
131
        ).setTabs(new ResourceTabs("tabs", "part", id, contextId, activeTab)));
×
132

133
        add(new Label("pagetitle", label + " (resource part) | nanodash"));
×
134
        add(new Label("name", label));
×
135
        add(new Label("titlesuffix", ResourceTabs.titleSuffix(activeTab)));
×
136
        add(new ExternalLinkWithActionsPanel("id", Model.of(id), Model.of(label), nanopubId == null ? Values.iri(id) : Values.iri(nanopubId)));
×
137

138
        final String nanopubRef = nanopubId == null ? "x:" : nanopubId;
×
139
        WebMarkupContainer contentContainer = new WebMarkupContainer("contentContainer");
×
140
        add(contentContainer);
×
141
        if (activeTab == ResourceTabs.Tab.ABOUT) {
×
142
            contentContainer.setVisible(false);
×
143
            // The panel constructor resolves view nanopubs over the network when they
144
            // aren't freshly cached, which would block the initial page render; the
145
            // view-id list must mirror the panel's View.get calls.
146
            add(LazyContentPanel.of("otherTab", markupId -> new AboutPartPanel(markupId, resourceWithProfile, id, classes),
×
147
                    AboutPartPanel.PART_INFO_VIEW, AboutResourcePanel.MAINTAINED_RESOURCE_PRESET_ASSIGNMENTS_VIEW, AboutPartPanel.PART_VIEW_DISPLAYS_VIEW));
148
        } else if (activeTab == ResourceTabs.Tab.EXPLORE) {
×
149
            contentContainer.setVisible(false);
×
150
            // The panel constructor resolves a view nanopub over the network when
151
            // it isn't freshly cached, which would block the initial page render.
152
            add(LazyContentPanel.of("otherTab", markupId -> new ExplorePanel(markupId, id),
×
153
                    ReferencesPage.REFERENCES_VIEW));
154
        } else if (activeTab == ResourceTabs.Tab.RAW) {
×
155
            contentContainer.setVisible(false);
×
156
            add(new DownloadRdfLinks("otherTab", "part", id, resourceWithProfile.getId()));
×
157
        } else {
158
            add(new EmptyPanel("otherTab").setVisible(false));
×
159
            if (resourceWithProfile.isDataInitialized()) {
×
160
                contentContainer.add(new ViewList("views", resourceWithProfile, id, nanopubRef, classes));
×
161
            } else {
162
                contentContainer.add(new AjaxLazyLoadPanel<Component>("views") {
×
163

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

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

174
                    @Override
175
                    public Component getLoadingComponent(String id) {
176
                        return new Label(id, "<div class=\"row-section\"><div class=\"col-12\">" + ResultComponent.getWaitIconHtml() + "</div></div>").setEscapeModelStrings(false);
×
177
                    }
178

179
                });
180
            }
181
        }
182
    }
×
183

184
    /**
185
     * Checks if auto-refresh is enabled for this page.
186
     *
187
     * @return true if auto-refresh is enabled, false otherwise
188
     */
189
    protected boolean hasAutoRefreshEnabled() {
190
        return true;
×
191
    }
192

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