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

knowledgepixels / nanodash / 18285433443

06 Oct 2025 03:08PM UTC coverage: 13.715% (+0.06%) from 13.658%
18285433443

push

github

tkuhn
refactor: Merge PublishConfirmPage into ExplorePage

447 of 4132 branches covered (10.82%)

Branch coverage included in aggregate %.

1162 of 7600 relevant lines covered (15.29%)

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

3
import java.util.HashMap;
4
import java.util.Map;
5

6
import org.apache.wicket.RestartResponseException;
7
import org.apache.wicket.markup.html.WebMarkupContainer;
8
import org.apache.wicket.markup.html.basic.Label;
9
import org.apache.wicket.markup.html.link.BookmarkablePageLink;
10
import org.apache.wicket.markup.html.link.ExternalLink;
11
import org.apache.wicket.request.flow.RedirectToUrlException;
12
import org.apache.wicket.request.mapper.parameter.PageParameters;
13
import org.apache.wicket.request.mapper.parameter.INamedParameters.NamedPair;
14
import org.commonjava.mimeparse.MIMEParse;
15
import org.nanopub.Nanopub;
16
import org.nanopub.NanopubUtils;
17
import org.nanopub.extra.security.SignatureUtils;
18
import org.nanopub.extra.services.ApiResponse;
19
import org.nanopub.extra.services.QueryRef;
20
import org.nanopub.vocabulary.NPX;
21
import org.nanopub.vocabulary.NTEMPLATE;
22
import org.slf4j.Logger;
23
import org.slf4j.LoggerFactory;
24

25
import com.google.common.collect.ArrayListMultimap;
26
import com.google.common.collect.Multimap;
27
import com.knowledgepixels.nanodash.GrlcQuery;
28
import com.knowledgepixels.nanodash.NanodashSession;
29
import com.knowledgepixels.nanodash.NanopubElement;
30
import com.knowledgepixels.nanodash.QueryApiAccess;
31
import com.knowledgepixels.nanodash.Space;
32
import com.knowledgepixels.nanodash.User;
33
import com.knowledgepixels.nanodash.Utils;
34
import com.knowledgepixels.nanodash.component.ExploreDataTable;
35
import com.knowledgepixels.nanodash.component.IriItem;
36
import com.knowledgepixels.nanodash.component.NanopubItem;
37
import com.knowledgepixels.nanodash.component.StatusLine;
38
import com.knowledgepixels.nanodash.component.ThingListPanel;
39
import com.knowledgepixels.nanodash.component.TitleBar;
40

41
import jakarta.servlet.http.HttpServletRequest;
42
import net.trustyuri.TrustyUriUtils;
43

44
/**
45
 * ExplorePage is a page that allows users to explore a specific Nanopublication or Thing.
46
 */
47
public class ExplorePage extends NanodashPage {
48

49
    private static final Logger logger = LoggerFactory.getLogger(ExplorePage.class);
×
50

51
    /**
52
     * The mount path for this page.
53
     */
54
    public static final String MOUNT_PATH = "/explore";
55

56
    /**
57
     * {@inheritDoc}
58
     */
59
    @Override
60
    public String getMountPath() {
61
        return MOUNT_PATH;
×
62
    }
63

64
    private Nanopub publishedNanopub = null;
×
65

66
    /**
67
     * Constructor for ExplorePage.
68
     *
69
     * @param parameters Page parameters containing the ID of the Nanopublication or Thing to explore.
70
     */
71
    public ExplorePage(final PageParameters parameters) {
72
        super(parameters);
×
73
        add(new Label("publish-confirm-panel").setVisible(false));
×
74
        initPage();
×
75
    }
×
76

77
    public ExplorePage(final Nanopub publishedNanopub, final PageParameters parameters) {
78
        super(parameters.add("id", publishedNanopub.getUri()));
×
79
        this.publishedNanopub = publishedNanopub;
×
80

81
        WebMarkupContainer publishConfirmPanel = new WebMarkupContainer("publish-confirm-panel");
×
82
        final NanodashSession session = NanodashSession.get();
×
83
        boolean hasKnownOwnLocalIntro = session.getLocalIntroCount() > 0;
×
84
        boolean someIntroJustNowPublished = Utils.usesPredicateInAssertion(publishedNanopub, NPX.DECLARED_BY);
×
85
        if (someIntroJustNowPublished) NanodashSession.get().setIntroPublishedNow();
×
86
        boolean lastIntroPublishedMoreThanFiveMinsAgo = session.getTimeSinceLastIntroPublished() > 5 * 60 * 1000;
×
87
        if (!hasKnownOwnLocalIntro && session.hasIntroPublished()) User.refreshUsers();
×
88
        publishConfirmPanel.add(new WebMarkupContainer("missing-intro-warning").setVisible(!hasKnownOwnLocalIntro && lastIntroPublishedMoreThanFiveMinsAgo));
×
89

90
        if (Utils.isNanopubOfClass(publishedNanopub, NTEMPLATE.ASSERTION_TEMPLATE)) {
×
91
            publishConfirmPanel.add(new WebMarkupContainer("use-template").add(
×
92
                    new BookmarkablePageLink<Void>("template-link", PublishPage.class, new PageParameters().add("template", publishedNanopub.getUri())))
×
93
            );
94
        } else {
95
            publishConfirmPanel.add(new WebMarkupContainer("use-template").add(new Label("template-link")).setVisible(false));
×
96
        }
97

98
        PageParameters plainLinkParams = new PageParameters();
×
99
        plainLinkParams.add("template", parameters.get("template"));
×
100
        if (!parameters.get("template-version").isEmpty()) {
×
101
            plainLinkParams.add("template-version", parameters.get("template-version"));
×
102
        }
103
        publishConfirmPanel.add(new BookmarkablePageLink<Void>("publish-another-link", PublishPage.class, plainLinkParams));
×
104

105
        PageParameters linkParams = new PageParameters(parameters);
×
106
        linkParams.remove("supersede");
×
107
        linkParams.remove("supersede-a");
×
108
        boolean publishAnotherFilledLinkVisible = false;
×
109
        for (NamedPair n : linkParams.getAllNamed()) {
×
110
            if (n.getKey().equals("template")) continue;
×
111
            if (n.getKey().equals("template-version")) continue;
×
112
            publishAnotherFilledLinkVisible = true;
×
113
        }
×
114
        if (publishAnotherFilledLinkVisible) {
×
115
            publishConfirmPanel.add(new BookmarkablePageLink<Void>("publish-another-filled-link", PublishPage.class, linkParams));
×
116
        } else {
117
            publishConfirmPanel.add(new Label("publish-another-filled-link", "").setVisible(false));
×
118
        }
119
        add(publishConfirmPanel);
×
120

121
        initPage();
×
122
    }
×
123

124
    private void initPage() {
125
        PageParameters parameters = getPageParameters();
×
126

127
        add(new TitleBar("titlebar", this, null));
×
128

129
        String tempRef = parameters.get("id").toString();
×
130

131
        WebMarkupContainer raw = new WebMarkupContainer("raw");
×
132
        add(raw);
×
133

134
        if (User.getUserData().isUser(tempRef)) {
×
135
            throw new RestartResponseException(UserPage.class, parameters);
×
136
        } else if (Space.get(tempRef) != null) {
×
137
            throw new RestartResponseException(SpacePage.class, parameters);
×
138
        }
139

140
        Map<String, String> nanopubParams = new HashMap<>();
×
141
        nanopubParams.put("ref", tempRef);
×
142
        Nanopub np = Utils.getAsNanopub(tempRef);
×
143
        boolean isNanopubId = (np != null);
×
144
        if (isNanopubId) {
×
145
            tempRef = np.getUri().stringValue();
×
146
        }
147
        if (!isNanopubId && tempRef.matches("^(.*[^A-Za-z0-9-_])?RA[A-Za-z0-9-_]{43}[^A-Za-z0-9-_].*$")) {
×
148
            np = Utils.getAsNanopub(tempRef.replaceFirst("^(.*[^A-Za-z0-9-_])?(RA[A-Za-z0-9-_]{43})[^A-Za-z0-9-_].*$", "$2"));
×
149
            if (np != null) {
×
150
                String npId = np.getUri().stringValue();
×
151
                tempRef = npId + tempRef.replaceFirst("^(.*[^A-Za-z0-9-_])?(RA[A-Za-z0-9-_]{43})([^A-Za-z0-9-_].*)$", "$3");
×
152
                Multimap<String, String> params = ArrayListMultimap.create();
×
153
                params.put("thing", tempRef);
×
154
                params.put("np", npId);
×
155
                ApiResponse resp = QueryApiAccess.forcedGet(new QueryRef("get-latest-thing-nanopub", params));
×
156
                if (!resp.getData().isEmpty()) {
×
157
                    // TODO We take the most recent in case more than one latest version exists. Make other latest versions visible too.
158
                    npId = resp.getData().get(0).get("latestVersion");
×
159
                }
160
                np = Utils.getAsNanopub(npId);
×
161
            }
162
        }
163
        if (np == null) {
×
164
            raw.setVisible(false);
×
165
            add(new Label("nanopub-header", ""));
×
166
            add(new Label("nanopub", ""));
×
167
            add(new WebMarkupContainer("use-template").setVisible(false));
×
168
            add(new WebMarkupContainer("run-query").setVisible(false));
×
169
        } else {
170

171
            // Check whether we should redirect to Nanopub Registry for machine-friendly formats:
172
            String mimeType = Utils.TYPE_HTML;
×
173
            try {
174
                HttpServletRequest httpRequest = (HttpServletRequest) getRequest().getContainerRequest();
×
175
                mimeType = MIMEParse.bestMatch(Utils.SUPPORTED_TYPES_LIST, httpRequest.getHeader("Accept"));
×
176
            } catch (Exception ex) {
×
177
                logger.error("Error determining MIME type from Accept header.", ex);
×
178
            }
×
179
            if (!mimeType.equals(Utils.TYPE_HTML)) {
×
180
                logger.info("Non-HTML content type: {}", mimeType);
×
181
                // TODO Make this registry URL configurable/dynamic:
182
                String redirectUrl = Utils.getMainRegistryUrl() + "np/" + TrustyUriUtils.getArtifactCode(np.getUri().stringValue());
×
183
                logger.info("Redirecting to: {}", redirectUrl);
×
184
                throw new RedirectToUrlException(redirectUrl, 302);
×
185
            }
186

187
            String nanopubHeaderLabel = "<h4>%s</h4>";
×
188
            if (isNanopubId) {
×
189
                nanopubHeaderLabel = String.format(nanopubHeaderLabel, "Nanopublication");
×
190
            } else {
191
                nanopubHeaderLabel = String.format(nanopubHeaderLabel, "Minted in Nanopublication");
×
192
            }
193
            add(new Label("nanopub-header", nanopubHeaderLabel).setEscapeModelStrings(false));
×
194
            add(new NanopubItem("nanopub", NanopubElement.get(np)));
×
195
            String url = Utils.getMainRegistryUrl() + "np/" + TrustyUriUtils.getArtifactCode(np.getUri().stringValue());
×
196
            raw.add(new ExternalLink("trig-txt", url + ".trig.txt"));
×
197
            raw.add(new ExternalLink("jsonld-txt", url + ".jsonld.txt"));
×
198
            raw.add(new ExternalLink("nq-txt", url + ".nq.txt"));
×
199
            raw.add(new ExternalLink("xml-txt", url + ".xml.txt"));
×
200
            raw.add(new ExternalLink("trig", url + ".trig"));
×
201
            raw.add(new ExternalLink("jsonld", url + ".jsonld"));
×
202
            raw.add(new ExternalLink("nq", url + ".nq"));
×
203
            raw.add(new ExternalLink("xml", url + ".xml"));
×
204
            if (Utils.isNanopubOfClass(np, NTEMPLATE.ASSERTION_TEMPLATE)) {
×
205
                add(new WebMarkupContainer("use-template").add(new BookmarkablePageLink<Void>("template-link", PublishPage.class, new PageParameters().add("template", np.getUri()))));
×
206
            } else {
207
                add(new WebMarkupContainer("use-template").setVisible(false));
×
208
            }
209
            if (Utils.isNanopubOfClass(np, GrlcQuery.GRLC_QUERY_CLASS)) {
×
210
                add(new WebMarkupContainer("run-query").add(new BookmarkablePageLink<Void>("query-link", QueryPage.class, new PageParameters().add("id", np.getUri()))));
×
211
            } else {
212
                add(new WebMarkupContainer("run-query").setVisible(false));
×
213
            }
214
        }
215

216
        final String ref = tempRef;
×
217
        final String shortName;
218
        if (publishedNanopub != null) {
×
219
            shortName = NanopubUtils.getLabel(np);
×
220
        } else if (parameters.get("label").isEmpty()) {
×
221
            shortName = IriItem.getShortNameFromURI(ref);
×
222
        } else {
223
            shortName = parameters.get("label").toString();
×
224
        }
225
        add(new Label("pagetitle", shortName + " (explore) | nanodash"));
×
226
        add(new Label("termname", shortName));
×
227
        add(new ExternalLink("urilink", ref, ref));
×
228
        if (publishedNanopub != null) {
×
229
            add(new Label("statusline", "<h4>Status</h4><p>Successfully published.</p>").setEscapeModelStrings(false));
×
230
        } else if (isNanopubId && SignatureUtils.seemsToHaveSignature(np)) {
×
231
            add(StatusLine.createComponent("statusline", ref));
×
232
        } else {
233
            add(new Label("statusline").setVisible(false));
×
234
        }
235
        if (publishedNanopub != null) {
×
236
            add(new Label("classes-panel").setVisible(false));
×
237
        } else {
238
            add(ThingListPanel.createComponent("classes-panel", ThingListPanel.Mode.CLASSES, ref, "<em>Searching for classes...</em>"));
×
239
        }
240
        if (isNanopubId) {
×
241
            add(new Label("instances-panel").setVisible(false));
×
242
            add(new Label("parts-panel").setVisible(false));
×
243
            add(new Label("templates-panel").setVisible(false));
×
244
        } else {
245
            add(ThingListPanel.createComponent("instances-panel", ThingListPanel.Mode.INSTANCES, ref, "<em>Searching for instances...</em>"));
×
246
            add(ThingListPanel.createComponent("parts-panel", ThingListPanel.Mode.PARTS, ref, "<em>Searching for parts...</em>"));
×
247
            add(ThingListPanel.createComponent("templates-panel", ThingListPanel.Mode.TEMPLATES, ref, "<em>Searching for templates...</em>"));
×
248
        }
249
        add(ExploreDataTable.createComponent("reftable", ref));
×
250
    }
×
251

252
    @Override
253
    protected void onBeforeRender() {
254
        if (publishedNanopub != null && !getPageParameters().get("postpub-redirect-url").isNull()) {
×
255
            String forwardUrl = getPageParameters().get("postpub-redirect-url").toString();
×
256
            if (forwardUrl.contains("?")) {
×
257
                // TODO: Add here URI of created nanopublication too?
258
                throw new RedirectToUrlException(forwardUrl);
×
259
            } else {
260
                String paramString = Utils.getPageParametersAsString(new PageParameters().add("id", publishedNanopub.getUri()));
×
261
                throw new RedirectToUrlException(forwardUrl + "?" + paramString);
×
262
            }
263
        }
264
        super.onBeforeRender();
×
265
    }
×
266

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