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

knowledgepixels / nanodash / 27145358627

08 Jun 2026 02:39PM UTC coverage: 20.682% (-0.3%) from 20.947%
27145358627

push

github

web-flow
Merge pull request #479 from knowledgepixels/feat/about-pages-478

Resource-page tabs, presets, and role-gated view actions (#478, #302)

1052 of 6429 branches covered (16.36%)

Branch coverage included in aggregate %.

2642 of 11432 relevant lines covered (23.11%)

3.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/ProfileIntroItem.java
1
package com.knowledgepixels.nanodash.component;
2

3
import com.knowledgepixels.nanodash.NanodashPreferences;
4
import com.knowledgepixels.nanodash.NanodashSession;
5
import com.knowledgepixels.nanodash.domain.User;
6
import com.knowledgepixels.nanodash.Utils;
7
import com.knowledgepixels.nanodash.page.ExplorePage;
8
import com.knowledgepixels.nanodash.page.PublishPage;
9
import com.knowledgepixels.nanodash.page.UserPage;
10
import net.trustyuri.TrustyUriUtils;
11
import org.apache.commons.codec.Charsets;
12
import org.apache.wicket.markup.html.WebMarkupContainer;
13
import org.apache.wicket.markup.html.basic.Label;
14
import org.apache.wicket.markup.html.link.ExternalLink;
15
import org.apache.wicket.markup.html.panel.Panel;
16
import org.apache.wicket.markup.repeater.Item;
17
import org.apache.wicket.markup.repeater.data.DataView;
18
import org.apache.wicket.markup.repeater.data.ListDataProvider;
19
import org.eclipse.rdf4j.model.IRI;
20
import org.nanopub.SimpleTimestampPattern;
21
import org.nanopub.extra.security.KeyDeclaration;
22
import org.nanopub.extra.setting.IntroNanopub;
23

24
import java.net.URLEncoder;
25
import java.util.Calendar;
26
import java.util.HashMap;
27
import java.util.Map;
28

29
import static com.knowledgepixels.nanodash.Utils.urlEncode;
30

31
/**
32
 * A panel that shows the user's introduction nanopubs.
33
 */
34
public class ProfileIntroItem extends Panel {
35

36
    private NanodashSession session = NanodashSession.get();
×
37
    private NanodashPreferences prefs = NanodashPreferences.get();
×
38
    private int recommendedActionsCount = 0;
×
39
    private Map<IntroNanopub, String> includeKeysParamMap = new HashMap<>();
×
40
    private int approvedIntrosCount = 0;
×
41

42
    /**
43
     * Constructor.
44
     *
45
     * @param id the component id
46
     */
47
    public ProfileIntroItem(String id) {
48
        super(id);
×
49

50
        String userPageUrl = UserPage.MOUNT_PATH + "?id=" + urlEncode(session.getUserIri());
×
51
        String publishIntroLinkString = PublishPage.MOUNT_PATH +
×
52
                                        "?template=http://purl.org/np/RAT8ayO62s4SFqDY1qjv24Iw0xarpbpc6zH68n7hRsAsA&" +
53
                                        "param_user=" + urlEncode(session.getUserIri()) + "&" +
×
54
//                                "param_name=" + urlEncode(session.getOrcidName()) + "&" +
55
                                        "param_public-key=" + urlEncode(session.getPubkeyString()) + "&" +
×
56
                                        "param_key-declaration=" + urlEncode(Utils.getShortPubkeyName(session.getPubkeyString())) + "&" +
×
57
                                        "param_key-declaration-ref=" + urlEncode(Utils.getShortPubkeyName(session.getPubkeyString())) + "&" +
×
58
                                        "param_key-location=" + urlEncode(prefs.getWebsiteUrl()) + "&" +
×
59
                                        "postpub-redirect-url=" + urlEncode(userPageUrl) + "&" +
×
60
                                        "link-message=" + urlEncode("Check the checkbox at the end of this page and press 'Publish' to publish this " +
×
61
                                                                    "introduction linking your ORCID identifier to the local key used on this site.");
62

63
        // Do this here, so we know whether to show the recommended action before rendering stage:
64
        if (session.getLocalIntro() != null) {
×
65
            for (IntroNanopub inp : session.getUserIntroNanopubs()) {
×
66
                if (User.isApproved(inp)) approvedIntrosCount++;
×
67
                String params = "";
×
68
                int paramIndex = 0;
×
69
                for (KeyDeclaration kd : inp.getKeyDeclarations()) {
×
70
                    if (!hasKey(session.getLocalIntro(), kd)) {
×
71
                        paramIndex++;
×
72
                        params += "&" +
×
73
                                  "param_public-key__." + paramIndex + "=" + urlEncode(kd.getPublicKeyString()) + "&" +
×
74
                                  "param_key-declaration__." + paramIndex + "=" + urlEncode(Utils.getShortPubkeyName(kd.getPublicKeyString())) + "&" +
×
75
                                  "param_key-declaration-ref__." + paramIndex + "=" + urlEncode(Utils.getShortPubkeyName(kd.getPublicKeyString())) + "&" +
×
76
                                  "param_key-location__." + paramIndex + "=" + urlEncode(kd.getKeyLocation() == null ? "" : kd.getKeyLocation());
×
77
                    }
78
                }
×
79
                if (paramIndex > 0) {
×
80
                    includeKeysParamMap.put(inp, params);
×
81
                }
82
            }
×
83
        }
84

85
        WebMarkupContainer publishIntroItem = new WebMarkupContainer("publish-intro-item");
×
86
        publishIntroItem.add(new ExternalLink("publish-intro-link", publishIntroLinkString, "Create Introduction"));
×
87
        add(publishIntroItem);
×
88
        publishIntroItem.setVisible(session.getLocalIntroCount() == 0);
×
89
        if (publishIntroItem.isVisible()) recommendedActionsCount++;
×
90

91
        WebMarkupContainer includeKeysItem = new WebMarkupContainer("include-keys-item");
×
92
        add(includeKeysItem);
×
93
        includeKeysItem.setVisible(!includeKeysParamMap.isEmpty());
×
94
        if (includeKeysItem.isVisible()) recommendedActionsCount++;
×
95

96
        WebMarkupContainer retractIntroItem = new WebMarkupContainer("retract-intro-item");
×
97
        add(retractIntroItem);
×
98
        retractIntroItem.setVisible(session.getLocalIntroCount() > 1);
×
99
        if (retractIntroItem.isVisible()) recommendedActionsCount++;
×
100

101
        WebMarkupContainer deriveIntroItem = new WebMarkupContainer("derive-intro-item");
×
102
        add(deriveIntroItem);
×
103
        deriveIntroItem.setVisible(session.getLocalIntroCount() == 0 && !session.getUserIntroNanopubs().isEmpty());
×
104
        if (deriveIntroItem.isVisible()) recommendedActionsCount++;
×
105

106
        WebMarkupContainer updateApprovedItem = new WebMarkupContainer("update-approved-item");
×
107
        add(updateApprovedItem);
×
108
        updateApprovedItem.setVisible(!session.isPubkeyApproved() && approvedIntrosCount > 0 && session.getLocalIntroCount() > 0);
×
109
        if (updateApprovedItem.isVisible()) recommendedActionsCount++;
×
110

111
        WebMarkupContainer getApprovalItem = new WebMarkupContainer("get-approval-item");
×
112
        String introUrl = (session.getLocalIntro() == null ? "" : session.getLocalIntro().getNanopub().getUri().stringValue());
×
113
        getApprovalItem.add(new ExternalLink("introduction-to-be-approved", introUrl, introUrl));
×
114
        add(getApprovalItem);
×
115
        getApprovalItem.setVisible(!session.isPubkeyApproved() && session.getLocalIntroCount() == 1);
×
116
        if (getApprovalItem.isVisible()) recommendedActionsCount++;
×
117

118
        WebMarkupContainer orcidLinkingItem = new WebMarkupContainer("orcid-linking-item");
×
119
        add(orcidLinkingItem);
×
120
        orcidLinkingItem.setVisible(false);
×
121
//                orcidLinkingItem.setVisible(!session.isOrcidLinked() && session.getLocalIntroCount() == 1);
122
        if (orcidLinkingItem.isVisible()) recommendedActionsCount++;
×
123

124
        if (session.getUserIntroNanopubs().isEmpty()) {
×
125
            add(new Label("intro-note", "<em>There are no introductions yet.</em>").setEscapeModelStrings(false));
×
126
        } else if (session.getLocalIntroCount() == 0) {
×
127
            // TODO: Check whether it's part of an introduction for a different ORCID, and show a warning if so
128
            add(new Label("intro-note", "The local key from this site is <strong class=\"negative\">not part of an introduction</strong> yet.").setEscapeModelStrings(false));
×
129
        } else if (session.getLocalIntroCount() == 1) {
×
130
            add(new Label("intro-note", ""));
×
131
        } else {
132
            // The "multiple introductions from this site" message is shown in the
133
            // retract recommended-action bullet instead.
134
            add(new Label("intro-note", ""));
×
135
        }
136
        if (recommendedActionsCount == 0) {
×
137
            add(new Label("action-note", "<em>There are no recommended actions.</em>").setEscapeModelStrings(false));
×
138
        } else if (recommendedActionsCount == 1) {
×
139
            add(new Label("action-note", "It is recommended that you <strong>execute this action</strong>:").setEscapeModelStrings(false));
×
140
        } else {
141
            add(new Label("action-note", "It is recommended that you <strong>execute one of these actions</strong>:").setEscapeModelStrings(false));
×
142
        }
143

144
        add(new DataView<IntroNanopub>("intro-nps", new ListDataProvider<IntroNanopub>(session.getUserIntroNanopubs())) {
×
145

146
            @Override
147
            protected void populateItem(Item<IntroNanopub> item) {
148
                final IntroNanopub inp = item.getModelObject();
×
149
                IRI location = Utils.getLocation(inp);
×
150
                String uri = inp.getNanopub().getUri().stringValue();
×
151
                ExternalLink link = new ExternalLink("intro-uri", ExplorePage.MOUNT_PATH + "?id=" + URLEncoder.encode(uri, Charsets.UTF_8));
×
152
                link.add(new Label("intro-uri-label", TrustyUriUtils.getArtifactCode(uri).substring(0, 10)));
×
153
                item.add(link);
×
154
                if (User.isApproved(inp)) {
×
155
                    item.add(new Label("intro-note", " <strong class=\"positive\">(approved)</strong>").setEscapeModelStrings(false));
×
156
                } else {
157
                    item.add(new Label("intro-note", ""));
×
158
                }
159
                if (session.isIntroWithLocalKey(inp)) {
×
160
                    item.add(new Label("location", "<strong>this site</strong>").setEscapeModelStrings(false));
×
161
                } else if (location == null) {
×
162
                    item.add(new Label("location", "unknown site"));
×
163
                } else {
164
                    item.add(new Label("location", "<a href=\"" + location + "\">" + location + "</a>").setEscapeModelStrings(false));
×
165
                }
166
                Calendar creationDate = SimpleTimestampPattern.getCreationTime(inp.getNanopub());
×
167
                item.add(new Label("date", (creationDate == null ? "unknown date" : NanopubItem.simpleDateFormat.format(creationDate.getTime()))));
×
168

169
                ExternalLink retractLink = new ExternalLink("retract-link", PublishPage.MOUNT_PATH + "?" +
×
170
                                                                            "template=http://purl.org/np/RA0QOsYNphQCityVcDIJEuldhhuJOX3GlBLw6QylRBhEI&" +
171
                                                                            "param_nanopubToBeRetracted=" + urlEncode(inp.getNanopub().getUri()) + "&" +
×
172
                                                                            "link-message=" + urlEncode("Check the checkbox at the end of this page and press 'Publish' to retract the " +
×
173
                                                                                                        "given introduction."),
174
                        "retract...");
175
                item.add(retractLink);
×
176
                retractLink.setVisible(session.getLocalIntroCount() > 1 && session.isIntroWithLocalKey(inp));
×
177

178
                ExternalLink deriveLink = new ExternalLink("derive-link", PublishPage.MOUNT_PATH + "?" +
×
179
                                                                          "template=http://purl.org/np/RAT8ayO62s4SFqDY1qjv24Iw0xarpbpc6zH68n7hRsAsA&" +
180
                                                                          "derive-a=" + urlEncode(inp.getNanopub().getUri()) + "&" +
×
181
                                                                          "param_public-key__.1=" + urlEncode(session.getPubkeyString()) + "&" +
×
182
                                                                          "param_key-declaration__.1=" + urlEncode(Utils.getShortPubkeyName(session.getPubkeyString())) + "&" +
×
183
                                                                          "param_key-declaration-ref__.1=" + urlEncode(Utils.getShortPubkeyName(session.getPubkeyString())) + "&" +
×
184
                                                                          "param_key-location__.1=" + urlEncode(prefs.getWebsiteUrl()) + "&" +
×
185
                                                                          "link-message=" + urlEncode("Enter you name below, check the checkbox at the end of the page, and press 'Publish' to publish this " +
×
186
                                                                                                      "introduction linking your ORCID identifier to the given keys."),
187
                        "derive new introduction...");
188
                item.add(deriveLink);
×
189
                deriveLink.setVisible(!session.isIntroWithLocalKey(inp) && session.getLocalIntroCount() == 0);
×
190

191
                if (includeKeysParamMap.containsKey(inp)) {
×
192
                    item.add(new ExternalLink("include-keys-link", PublishPage.MOUNT_PATH + "?" +
×
193
                                                                   "template=http://purl.org/np/RAT8ayO62s4SFqDY1qjv24Iw0xarpbpc6zH68n7hRsAsA&" +
194
                                                                   "supersede=" + urlEncode(session.getLocalIntro().getNanopub().getUri()) +
×
195
                                                                   includeKeysParamMap.get(inp) + "&" +
×
196
                                                                   "link-message=" + urlEncode("Check the checkbox at the end of this page and press 'Publish' to publish this " +
×
197
                                                                                               "introduction that includes the additional keys."),
198
                            "include keys..."));
199
                } else {
200
                    item.add(new ExternalLink("include-keys-link", ".", "").setVisible(false));
×
201
                }
202

203
                item.add(new DataView<>("intro-keys", new ListDataProvider<>(inp.getKeyDeclarations())) {
×
204

205
                    @Override
206
                    protected void populateItem(Item<KeyDeclaration> kdi) {
207
                        kdi.add(new Label("intro-key", Utils.getShortPubkeyName(Utils.createSha256HexHash(kdi.getModelObject().getPublicKeyString()))));
×
208
                    }
×
209

210
                });
211
            }
×
212

213
        });
214

215
    }
×
216

217
    private boolean hasKey(IntroNanopub inp, KeyDeclaration kd) {
218
        // TODO: Do this more efficiently:
219
        for (KeyDeclaration k : inp.getKeyDeclarations()) {
×
220
            if (k.getPublicKeyString().equals(kd.getPublicKeyString())) return true;
×
221
        }
×
222
        return false;
×
223
    }
224

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