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

knowledgepixels / nanodash / 27622310436

16 Jun 2026 01:49PM UTC coverage: 26.963% (+6.3%) from 20.697%
27622310436

Pull #483

github

web-flow
Merge dbba567c9 into 663f14f46
Pull Request #483: Space/resource About pages, ref-aware spaces, and magic query params

1542 of 6717 branches covered (22.96%)

Branch coverage included in aggregate %.

3407 of 11638 relevant lines covered (29.27%)

4.31 hits per line

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

0.0
src/main/java/com/knowledgepixels/nanodash/component/QueryResultListBuilder.java
1
package com.knowledgepixels.nanodash.component;
2

3
import com.knowledgepixels.nanodash.*;
4
import com.knowledgepixels.nanodash.domain.AbstractResourceWithProfile;
5
import com.knowledgepixels.nanodash.domain.MaintainedResource;
6
import com.knowledgepixels.nanodash.domain.Space;
7
import com.knowledgepixels.nanodash.page.PublishPage;
8
import com.knowledgepixels.nanodash.repository.MaintainedResourceRepository;
9
import com.knowledgepixels.nanodash.template.Template;
10
import org.apache.wicket.Component;
11
import org.apache.wicket.behavior.AttributeAppender;
12
import org.apache.wicket.request.mapper.parameter.PageParameters;
13
import org.eclipse.rdf4j.model.IRI;
14
import org.nanopub.extra.services.ApiResponse;
15
import org.nanopub.extra.services.QueryRef;
16

17
import java.io.Serializable;
18

19
/**
20
 * Builder class for creating QueryResultList components.
21
 */
22
public class QueryResultListBuilder implements Serializable {
23

24
    private String markupId;
25
    private ViewDisplay viewDisplay;
26
    private String contextId = null;
×
27
    private QueryRef queryRef;
28
    private AbstractResourceWithProfile resourceWithProfile = null;
×
29
    private String id = null;
×
30
    private AbstractResourceWithProfile pageResource = null;
×
31
    private String postPublishTab = null;
×
32

33
    private QueryResultListBuilder(String markupId, QueryRef queryRef, ViewDisplay viewDisplay) {
×
34
        this.markupId = markupId;
×
35
        // Bind session-derived "magic" query parameters here on the request thread
36
        // (ApiCache fetches on background threads where the session is absent).
37
        this.queryRef = com.knowledgepixels.nanodash.MagicQueryParams.augment(queryRef);
×
38
        this.viewDisplay = viewDisplay;
×
39
    }
×
40

41
    /**
42
     * Creates a new QueryResultListBuilder instance.
43
     *
44
     * @param markupId    the markup ID for the component
45
     * @param queryRef    the query reference
46
     * @param viewDisplay the view display
47
     * @return a new QueryResultListBuilder instance
48
     */
49
    public static QueryResultListBuilder create(String markupId, QueryRef queryRef, ViewDisplay viewDisplay) {
50
        return new QueryResultListBuilder(markupId, queryRef, viewDisplay);
×
51
    }
52

53
    public QueryResultListBuilder resourceWithProfile(AbstractResourceWithProfile resourceWithProfile) {
54
        this.resourceWithProfile = resourceWithProfile;
×
55
        return this;
×
56
    }
57

58
    /**
59
     * Sets the context ID for the QueryResultList.
60
     *
61
     * @param contextId the context ID
62
     * @return the current QueryResultListBuilder instance
63
     */
64
    public QueryResultListBuilder contextId(String contextId) {
65
        this.contextId = contextId;
×
66
        return this;
×
67
    }
68

69
    public QueryResultListBuilder id(String id) {
70
        this.id = id;
×
71
        return this;
×
72
    }
73

74
    public QueryResultListBuilder pageResource(AbstractResourceWithProfile pageResource) {
75
        this.pageResource = pageResource;
×
76
        return this;
×
77
    }
78

79
    /**
80
     * Sets the tab to return to after publishing one of this view's action
81
     * buttons (e.g. {@code "about"}). Null leaves the post-publish redirect on
82
     * its default tab.
83
     *
84
     * @param postPublishTab the tab name, or null for the default
85
     * @return the current QueryResultListBuilder instance
86
     */
87
    public QueryResultListBuilder postPublishTab(String postPublishTab) {
88
        this.postPublishTab = postPublishTab;
×
89
        return this;
×
90
    }
91

92
    /**
93
     * Builds the QueryResultList component.
94
     *
95
     * @return the QueryResultList component
96
     */
97
    public Component build() {
98
        ApiResponse response = ApiCache.retrieveResponseAsync(queryRef);
×
99
        String colClass = " col-" + viewDisplay.getDisplayWidth();
×
100
        if (resourceWithProfile != null) {
×
101
            if (response != null) {
×
102
                QueryResultList resultList = new QueryResultList(markupId, queryRef, response, viewDisplay);
×
103
                resultList.setResourceWithProfile(resourceWithProfile);
×
104
                resultList.setPageResource(pageResource);
×
105
                resultList.setContextId(contextId);
×
106
                resultList.setPostPublishTab(postPublishTab);
×
107
                View view = viewDisplay.getView();
×
108
                if (view != null) {
×
109
                    for (IRI actionIri : view.getViewResultActionList()) {
×
110
                        if (!SpaceMemberRole.isViewerEntitled(view.getActionVisibleTo(actionIri), resourceWithProfile)) continue;
×
111
                        Template t = view.getTemplateForAction(actionIri);
×
112
                        if (t == null) continue;
×
113
                        String targetField = view.getTemplateTargetFieldForAction(actionIri);
×
114
                        if (targetField == null) targetField = "resource";
×
115
                        String label = view.getLabelForAction(actionIri);
×
116
                        if (label == null) label = "action...";
×
117
                        if (!label.endsWith("...")) label += "...";
×
118
                        PageParameters params = new PageParameters().set("template", t.getId())
×
119
                                .set("param_" + targetField, id)
×
120
                                .set("context", contextId)
×
121
                                .set("template-version", "latest");
×
122
                        if (id != null && contextId != null && !id.equals(contextId)) {
×
123
                            params.set("part", id);
×
124
                        }
125
                        String partField = view.getTemplatePartFieldForAction(actionIri);
×
126
                        if (partField != null && contextId != null) {
×
127
                            // The part field pre-fills a namespaced child IRI (the user fills the suffix).
128
                            // TODO Find a better way to pass the MaintainedResource object to this method:
129
                            MaintainedResource r = MaintainedResourceRepository.get().findById(contextId);
×
130
                            String namespace = null;
×
131
                            if (r != null) {
×
132
                                namespace = r.getNamespace();
×
133
                            } else if (resourceWithProfile instanceof Space) {
×
134
                                // The Space-creation templates' `space` placeholder has a fixed
135
                                // `https://w3id.org/spaces/` prefix, so the pre-fill is relative to it.
136
                                // Nesting the new space's IRI under this space's path makes it a
137
                                // sub-space via the prefix match.
138
                                namespace = contextId.replaceFirst("https://w3id.org/spaces/", "") + "/";
×
139
                            }
140
                            if (namespace != null) {
×
141
                                params.set("param_" + partField, namespace + "<SET-SUFFIX>");
×
142
                            }
143
                        }
144
                        String queryMapping = view.getTemplateQueryMapping(actionIri);
×
145
                        if (queryMapping != null && queryMapping.contains(":")) {
×
146
                            params.set("values-from-query", queryRef.getAsUrlString());
×
147
                            params.set("values-from-query-mapping", queryMapping);
×
148
                        }
149
                        params.set("refresh-upon-publish", queryRef.getAsUrlString());
×
150
                        if (postPublishTab != null) params.set("postpub-tab", postPublishTab);
×
151
                        resultList.addButton(label, PublishPage.class, params);
×
152
                    }
×
153
                }
154
                resultList.add(new AttributeAppender("class", colClass));
×
155
                return resultList;
×
156
            } else {
157
                ApiResultComponent comp = new ApiResultComponent(markupId, queryRef) {
×
158
                    @Override
159
                    public Component getApiResultComponent(String markupId, ApiResponse response) {
160
                        QueryResultList resultList = new QueryResultList(markupId, queryRef, response, viewDisplay);
×
161
                        resultList.setResourceWithProfile(resourceWithProfile);
×
162
                        resultList.setPageResource(pageResource);
×
163
                        resultList.setContextId(contextId);
×
164
                        resultList.setPostPublishTab(postPublishTab);
×
165
                        View view = viewDisplay.getView();
×
166
                        if (view != null) {
×
167
                            for (IRI actionIri : view.getViewResultActionList()) {
×
168
                                if (!SpaceMemberRole.isViewerEntitled(view.getActionVisibleTo(actionIri), resourceWithProfile)) continue;
×
169
                                Template t = view.getTemplateForAction(actionIri);
×
170
                                if (t == null) continue;
×
171
                                String targetField = view.getTemplateTargetFieldForAction(actionIri);
×
172
                                if (targetField == null) targetField = "resource";
×
173
                                String label = view.getLabelForAction(actionIri);
×
174
                                if (label == null) label = "action...";
×
175
                                if (!label.endsWith("...")) label += "...";
×
176
                                PageParameters params = new PageParameters().set("template", t.getId())
×
177
                                        .set("param_" + targetField, id)
×
178
                                        .set("context", contextId)
×
179
                                        .set("template-version", "latest");
×
180
                                if (id != null && contextId != null && !id.equals(contextId)) {
×
181
                                    params.set("part", id);
×
182
                                }
183
                                String partField = view.getTemplatePartFieldForAction(actionIri);
×
184
                                if (partField != null && contextId != null) {
×
185
                                    // The part field pre-fills a namespaced child IRI (the user fills the suffix).
186
                                    // TODO Find a better way to pass the MaintainedResource object to this method:
187
                                    MaintainedResource r = MaintainedResourceRepository.get().findById(contextId);
×
188
                                    String namespace = null;
×
189
                                    if (r != null) {
×
190
                                        namespace = r.getNamespace();
×
191
                                    } else if (resourceWithProfile instanceof Space) {
×
192
                                        // The Space-creation templates' `space` placeholder has a fixed
193
                                        // `https://w3id.org/spaces/` prefix, so the pre-fill is relative to it.
194
                                        // Nesting the new space's IRI under this space's path makes it a
195
                                        // sub-space via the prefix match.
196
                                        namespace = contextId.replaceFirst("https://w3id.org/spaces/", "") + "/";
×
197
                                    }
198
                                    if (namespace != null) {
×
199
                                        params.set("param_" + partField, namespace + "<SET-SUFFIX>");
×
200
                                    }
201
                                }
202
                                String queryMapping = view.getTemplateQueryMapping(actionIri);
×
203
                                if (queryMapping != null && queryMapping.contains(":")) {
×
204
                                    params.set("values-from-query", queryRef.getAsUrlString());
×
205
                                    params.set("values-from-query-mapping", queryMapping);
×
206
                                }
207
                                params.set("refresh-upon-publish", queryRef.getAsUrlString());
×
208
                                if (postPublishTab != null) params.set("postpub-tab", postPublishTab);
×
209
                                resultList.addButton(label, PublishPage.class, params);
×
210
                            }
×
211
                        }
212
                        return resultList;
×
213
                    }
214
                };
215
                comp.add(new AttributeAppender("class", colClass));
×
216
                return comp;
×
217
            }
218
        } else {
219
            if (response != null) {
×
220
                QueryResultList resultList = new QueryResultList(markupId, queryRef, response, viewDisplay);
×
221
                resultList.setPageResource(pageResource);
×
222
                resultList.setContextId(contextId);
×
223
                resultList.add(new AttributeAppender("class", colClass));
×
224
                return resultList;
×
225
            } else {
226
                ApiResultComponent comp = new ApiResultComponent(markupId, queryRef) {
×
227
                    @Override
228
                    public Component getApiResultComponent(String markupId, ApiResponse response) {
229
                        QueryResultList resultList = new QueryResultList(markupId, queryRef, response, viewDisplay);
×
230
                        resultList.setPageResource(pageResource);
×
231
                        resultList.setContextId(contextId);
×
232
                        return resultList;
×
233
                    }
234
                };
235
                comp.add(new AttributeAppender("class", colClass));
×
236
                return comp;
×
237
            }
238
        }
239
    }
240

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