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

knowledgepixels / nanodash / 17837235071

18 Sep 2025 05:58PM UTC coverage: 13.87%. Remained the same
17837235071

push

github

tkuhn
chore: Remove serialVersionUIDs

443 of 4022 branches covered (11.01%)

Branch coverage included in aggregate %.

1133 of 7341 relevant lines covered (15.43%)

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/connector/GenOverviewPage.java
1
package com.knowledgepixels.nanodash.connector;
2

3
import com.knowledgepixels.nanodash.NanodashPreferences;
4
import com.knowledgepixels.nanodash.NanodashSession;
5
import com.knowledgepixels.nanodash.User;
6
import com.knowledgepixels.nanodash.Utils;
7
import com.knowledgepixels.nanodash.component.TitleBar;
8
import com.knowledgepixels.nanodash.page.OrcidLoginPage;
9
import com.knowledgepixels.nanodash.page.PublishPage;
10
import org.apache.wicket.ajax.AjaxRequestTarget;
11
import org.apache.wicket.ajax.markup.html.AjaxLink;
12
import org.apache.wicket.markup.html.WebMarkupContainer;
13
import org.apache.wicket.markup.html.basic.Label;
14
import org.apache.wicket.markup.html.image.Image;
15
import org.apache.wicket.markup.html.link.BookmarkablePageLink;
16
import org.apache.wicket.markup.html.link.ExternalLink;
17
import org.apache.wicket.markup.repeater.Item;
18
import org.apache.wicket.markup.repeater.data.DataView;
19
import org.apache.wicket.markup.repeater.data.ListDataProvider;
20
import org.apache.wicket.request.mapper.parameter.PageParameters;
21
import org.apache.wicket.request.resource.PackageResourceReference;
22
import org.eclipse.rdf4j.model.IRI;
23
import org.nanopub.Nanopub;
24
import org.nanopub.extra.services.ApiResponse;
25
import org.nanopub.extra.services.ApiResponseEntry;
26
import org.slf4j.Logger;
27
import org.slf4j.LoggerFactory;
28

29
import java.util.ArrayList;
30
import java.util.HashMap;
31
import java.util.List;
32

33
/**
34
 * Overview page for a connector journal.
35
 */
36
public class GenOverviewPage extends ConnectorPage {
37

38
    private static final Logger logger = LoggerFactory.getLogger(GenOverviewPage.class);
×
39

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

45
    private ConnectorConfig config;
46

47
    /**
48
     * Constructor for the overview page.
49
     *
50
     * @param params the page parameters, which should contain the journal ID
51
     */
52
    public GenOverviewPage(PageParameters params) {
53
        super(params);
×
54
        final String journalId = params.get("journal").toString();
×
55
        config = ConnectorConfig.get(journalId);
×
56

57
        add(new TitleBar("titlebar", this, "connectors"));
×
58
        add(new Image("logo", new PackageResourceReference(getConfig().getClass(), getConfig().getLogoFileName())));
×
59

60
        if (getConfig().getTechnicalEditorIds().contains(NanodashSession.get().getUserIri())) {
×
61
            WebMarkupContainer technicalEditorActions = new WebMarkupContainer("technical-editor-actions");
×
62

63
            technicalEditorActions.add(new BookmarkablePageLink<Void>("publish-article-metadata", PublishPage.class,
×
64
                    new PageParameters().add("template", "https://w3id.org/np/RA48p4Ct8tWL--rIc1Dcr2BcYpW_7X1pfuv_2LK3anolY")
×
65
                            .add("template-version", "latest")
×
66
                            .add("param_journal", getConfig().getJournalIssn())
×
67
                            .add("param_journal-title", getConfig().getJournalName())
×
68
                            .add("prtemplate", "https://w3id.org/np/RAekcN47h13fk6ZK4XiObgGgk-qB01sLOjyGyhMCq_jT4")
×
69
                            .add("pitemplate1", "https://w3id.org/np/RA5R_qv3VsZIrDKd8Mr37x3HoKCsKkwN5tJVqgQsKhjTE")
×
70
                            .add("piparam1_type", getConfig().getNanopubType() == null ? "" : getConfig().getNanopubType().stringValue())
×
71
                            .add("pitemplate2", "https://w3id.org/np/RA16U9Wo30ObhrK1NzH7EsmVRiRtvEuEA_Dfc-u8WkUCA")
×
72
                            .add("target-namespace", getConfig().getTargetNamespace() == null ? "https://w3id.org/np/" : getConfig().getTargetNamespace())
×
73
            ));
74
            add(technicalEditorActions);
×
75
        } else {
×
76
            add(new WebMarkupContainer("technical-editor-actions").setVisible(false));
×
77
        }
78

79
        try {
80

81
            final WebMarkupContainer c = new WebMarkupContainer("owncandidates-component");
×
82
            c.setOutputMarkupId(true);
×
83
            add(c);
×
84

85
            if (NanodashSession.get().getUserIri() != null) {
×
86

87
                HashMap<String, String> apiParam = new HashMap<>();
×
88
                apiParam.put("creator", NanodashSession.get().getUserIri().stringValue());
×
89
                ApiResponse resp = callApi(getConfig().getCandidateNanopubsApiCall(), apiParam);
×
90
                while (resp == null) {
×
91
                    // we only get here in case of second-generation API calls
92
                    // TODO Do this in an AJAX way:
93
                    try {
94
                        Thread.sleep(200);
×
95
                    } catch (InterruptedException ex) {
×
96
                        logger.error("Thread interrupted", ex);
×
97
                    }
×
98
                    resp = callApi(getConfig().getCandidateNanopubsApiCall(), apiParam);
×
99
                }
100

101
                final List<ApiResponseEntry> listData = new ArrayList<ApiResponseEntry>();
×
102
                final ArrayList<ApiResponseEntry> fullList = new ArrayList<>();
×
103
                for (ApiResponseEntry a : resp.getData()) {
×
104
                    if (listData.size() < 10) listData.add(a);
×
105
                    // TODO This will become inefficient at some point:
106
                    fullList.add(a);
×
107
                }
×
108

109
                c.add(new DataView<ApiResponseEntry>("own", new ListDataProvider<ApiResponseEntry>(listData)) {
×
110

111
                    @Override
112
                    protected void populateItem(Item<ApiResponseEntry> item) {
113
                        ApiResponseEntry e = item.getModelObject();
×
114
                        PageParameters params = new PageParameters().add("journal", journalId).add("id", e.get("np")).add("mode", "author");
×
115
                        BookmarkablePageLink<Void> l = new BookmarkablePageLink<Void>("ownlink", GenNanopubPage.class, params);
×
116
                        l.add(new Label("ownlinktext", "\"" + e.get("label") + "\""));
×
117
                        item.add(l);
×
118
                        String pubkeyhash = Utils.createSha256HexHash(e.get("pubkey"));
×
119
                        String username = User.getShortDisplayNameForPubkeyhash(null, pubkeyhash);
×
120
                        item.add(new Label("ownnote", "by " + username + " on " + e.get("date").substring(0, 10)));
×
121
                    }
×
122

123
                });
124

125
                c.add(new AjaxLink<>("allowncandidates") {
×
126

127
                    @Override
128
                    public void onClick(AjaxRequestTarget target) {
129
                        try {
130
                            listData.clear();
×
131
                            listData.addAll(fullList);
×
132
                            target.add(c);
×
133
                            setVisible(false);
×
134
                            target.add(this);
×
135
                        } catch (Exception ex) {
×
136
                            logger.error("Error showing all candidates", ex);
×
137
                        }
×
138
                    }
×
139

140
                }.setVisible(fullList.size() > 10));
×
141

142
                add(new BookmarkablePageLink<Void>("create-new", GenSelectPage.class, params));
×
143
            } else {
×
144
                c.add(new Label("allowncandidates", "").setVisible(false));
×
145
                c.add(new Label("own", "").setVisible(false));
×
146
                if (NanodashPreferences.get().isOrcidLoginMode()) {
×
147
                    String loginUrl = OrcidLoginPage.getOrcidLoginUrl(getMountPath(), getPageParameters());
×
148
                    add(new ExternalLink("create-new", loginUrl, "Login to See More"));
×
149
                } else {
×
150
                    add(new ExternalLink("create-new", Utils.getUrlWithParameters(getMountPath(), getPageParameters()), "Complete Your Profile to See More"));
×
151
                }
152
            }
153
        } catch (Exception ex) {
×
154
            logger.error("Error in own candidates section", ex);
×
155
        }
×
156

157
        try {
158
            final WebMarkupContainer c = new WebMarkupContainer("candidates-component");
×
159
            c.setOutputMarkupId(true);
×
160
            add(c);
×
161

162
            ApiResponse resp = callApi(getConfig().getCandidateNanopubsApiCall(), new HashMap<>());
×
163
            while (resp == null) {
×
164
                // TODO Do this in an AJAX way:
165
                try {
166
                    Thread.sleep(200);
×
167
                } catch (InterruptedException ex) {
×
168
                    logger.error("Thread interrupted", ex);
×
169
                }
×
170
                resp = callApi(getConfig().getCandidateNanopubsApiCall(), new HashMap<>());
×
171
            }
172

173
            final List<ApiResponseEntry> listData = new ArrayList<ApiResponseEntry>();
×
174
            final ArrayList<ApiResponseEntry> fullList = new ArrayList<>();
×
175
            for (ApiResponseEntry a : resp.getData()) {
×
176
                if (listData.size() < 10) listData.add(a);
×
177
                // TODO This will become inefficient at some point:
178
                fullList.add(a);
×
179
            }
×
180

181
            c.add(new DataView<ApiResponseEntry>("candidates", new ListDataProvider<ApiResponseEntry>(listData)) {
×
182

183
                @Override
184
                protected void populateItem(Item<ApiResponseEntry> item) {
185
                    ApiResponseEntry e = item.getModelObject();
×
186
                    PageParameters params = new PageParameters().add("journal", journalId).add("id", e.get("np")).add("mode", "candidate");
×
187
                    BookmarkablePageLink<Void> l = new BookmarkablePageLink<Void>("candidatelink", GenNanopubPage.class, params);
×
188
                    l.add(new Label("candidatelinktext", "\"" + e.get("label") + "\""));
×
189
                    item.add(l);
×
190
                    String pubkeyhash = Utils.createSha256HexHash(e.get("pubkey"));
×
191
                    String username = User.getShortDisplayNameForPubkeyhash(null, pubkeyhash);
×
192
                    item.add(new Label("candidatenote", "by " + username + " on " + e.get("date").substring(0, 10)));
×
193
                }
×
194

195
            });
196

197
            c.add(new AjaxLink<>("allcandidates") {
×
198

199
                @Override
200
                public void onClick(AjaxRequestTarget target) {
201
                    try {
202
                        listData.clear();
×
203
                        listData.addAll(fullList);
×
204
                        target.add(c);
×
205
                        setVisible(false);
×
206
                        target.add(this);
×
207
                    } catch (Exception ex) {
×
208
                        logger.error("Error in all candidates click", ex);
×
209
                    }
×
210
                }
×
211

212
            }.setVisible(fullList.size() > 10));
×
213

214
        } catch (Exception ex) {
×
215
            logger.error("Error in candidates section", ex);
×
216
        }
×
217

218
        if (getConfig().getAcceptedNanopubsApiCall() != null) {
×
219
            try {
220
                final WebMarkupContainer c = new WebMarkupContainer("accepted-component");
×
221
                c.setOutputMarkupId(true);
×
222
                add(c);
×
223

224
                ApiResponse resp = callApi(getConfig().getAcceptedNanopubsApiCall(), new HashMap<>());
×
225
                while (resp == null) {
×
226
                    // TODO Do this in an AJAX way:
227
                    try {
228
                        Thread.sleep(200);
×
229
                    } catch (InterruptedException ex) {
×
230
                        logger.error("Thread interrupted", ex);
×
231
                    }
×
232
                    resp = callApi(getConfig().getAcceptedNanopubsApiCall(), new HashMap<>());
×
233
                }
234

235
                final List<ApiResponseEntry> listData = new ArrayList<ApiResponseEntry>();
×
236
                final ArrayList<ApiResponseEntry> fullList = new ArrayList<>();
×
237
                for (ApiResponseEntry a : resp.getData()) {
×
238
                    if (listData.size() < 10) listData.add(a);
×
239
                    // TODO This will become inefficient at some point:
240
                    fullList.add(a);
×
241
                }
×
242

243
                c.add(new DataView<ApiResponseEntry>("accepted", new ListDataProvider<ApiResponseEntry>(listData)) {
×
244

245
                    @Override
246
                    protected void populateItem(Item<ApiResponseEntry> item) {
247
                        ApiResponseEntry e = item.getModelObject();
×
248
                        PageParameters params = new PageParameters().add("journal", journalId).add("id", e.get("np")).add("mode", "final");
×
249
                        BookmarkablePageLink<Void> l = new BookmarkablePageLink<Void>("acceptedlink", GenNanopubPage.class, params);
×
250
                        l.add(new Label("acceptedlinktext", "\"" + e.get("label") + "\""));
×
251
                        item.add(l);
×
252
                        IRI firstAuthorIri = Utils.vf.createIRI(e.get("firstAuthor"));
×
253

254
                        // TODO Move this user name extraction to a helper method:
255
                        String username;
256
                        if (User.getName(firstAuthorIri) != null) {
×
257
                            username = User.getShortDisplayName(firstAuthorIri);
×
258
                        } else {
259
                            try {
260
                                Nanopub np = Utils.getAsNanopub(e.get("np"));
×
261
                                username = Utils.getFoafNameMap(np).get(e.get("firstAuthor"));
×
262
                            } catch (Exception ex) {
×
263
                                logger.error("Error getting FOAF name for {} in {}", e.get("firstAuthor"), e.get("np"), ex);
×
264
                                username = User.getShortDisplayName(firstAuthorIri);
×
265
                            }
×
266
                        }
267

268
                        item.add(new Label("acceptednote", "by " + username + " on " + e.get("date").substring(0, 10)));
×
269
                    }
×
270

271
                });
272

273
                c.add(new AjaxLink<>("allaccepted") {
×
274

275
                    @Override
276
                    public void onClick(AjaxRequestTarget target) {
277
                        try {
278
                            listData.clear();
×
279
                            listData.addAll(fullList);
×
280
                            target.add(c);
×
281
                            setVisible(false);
×
282
                            target.add(this);
×
283
                        } catch (Exception ex) {
×
284
                            logger.error("Error showing all accepted", ex);
×
285
                        }
×
286
                    }
×
287

288
                }.setVisible(fullList.size() > 10));
×
289

290
            } catch (Exception ex) {
×
291
                logger.error("Error in accepted section", ex);
×
292
            }
×
293
        }
294

295
        if (getConfig().getGeneralReactionsApiCall() != null) {
×
296
            try {
297
                final WebMarkupContainer c = new WebMarkupContainer("reactions-component");
×
298
                c.setOutputMarkupId(true);
×
299
                add(c);
×
300

301
                ApiResponse resp = callApi(getConfig().getGeneralReactionsApiCall(), new HashMap<>());
×
302
                while (resp == null) {
×
303
                    // TODO Do this in an AJAX way:
304
                    try {
305
                        Thread.sleep(200);
×
306
                    } catch (InterruptedException ex) {
×
307
                        logger.error("Thread interrupted", ex);
×
308
                    }
×
309
                    resp = callApi(getConfig().getGeneralReactionsApiCall(), new HashMap<>());
×
310
                }
311

312
                final List<ApiResponseEntry> listData = new ArrayList<ApiResponseEntry>();
×
313
                final ArrayList<ApiResponseEntry> fullList = new ArrayList<>();
×
314
                for (ApiResponseEntry a : resp.getData()) {
×
315
                    if (listData.size() < 10) listData.add(a);
×
316
                    // TODO This will become inefficient at some point:
317
                    fullList.add(a);
×
318
                }
×
319

320
                c.add(new DataView<ApiResponseEntry>("reactions", new ListDataProvider<ApiResponseEntry>(listData)) {
×
321

322
                    @Override
323
                    protected void populateItem(Item<ApiResponseEntry> item) {
324
                        ApiResponseEntry e = item.getModelObject();
×
325
                        PageParameters params = new PageParameters().add("journal", journalId).add("id", e.get("ref_np")).add("mode", "candidate");
×
326
                        BookmarkablePageLink<Void> l = new BookmarkablePageLink<Void>("reactionlink", GenNanopubPage.class, params);
×
327
                        l.add(new Label("reactionlinktext", "\"" + e.get("comment") + "\""));
×
328
                        item.add(l);
×
329
                        String pubkeyhash = Utils.createSha256HexHash(e.get("pubkey"));
×
330
                        String username = User.getShortDisplayNameForPubkeyhash(null, pubkeyhash);
×
331
                        item.add(new Label("reactionnote", "by " + username + " on " + e.get("date").substring(0, 10)));
×
332
                    }
×
333

334
                });
335

336
                c.add(new AjaxLink<>("allreactions") {
×
337

338
                    @Override
339
                    public void onClick(AjaxRequestTarget target) {
340
                        try {
341
                            listData.clear();
×
342
                            listData.addAll(fullList);
×
343
                            target.add(c);
×
344
                            setVisible(false);
×
345
                            target.add(this);
×
346
                        } catch (Exception ex) {
×
347
                            logger.error("Error showing all reactions", ex);
×
348
                        }
×
349
                    }
×
350

351
                }.setVisible(fullList.size() > 10));
×
352

353
            } catch (Exception ex) {
×
354
                logger.error("Error in reactions section", ex);
×
355
            }
×
356
        }
357

358
        add(new Label("pagetitle", config.getJournalName() + " | nanodash"));
×
359
        add(new Label("journal-name-title", config.getJournalName()));
×
360
        add(new ExternalLink("journal-link", config.getJournalUrl(), config.getJournalName()));
×
361
        add(new Label("extra-instructions", config.getExtraInstructions()).setEscapeModelStrings(false));
×
362

363
        if (getConfig().getGeneralReactionsApiCall() == null) {
×
364
            // TODO Fix this in OverviewPage code once refactoring is finished:
365
            add(new Label("reactions-component").setVisible(false));
×
366
        }
367
        add(new ExternalLink("support-link", "mailto:contact-project+knowledgepixels-support-desk@incoming.gitlab.com?subject=[" + config.getJournalAbbrev() + "%20general]%20my%20problem/question&body=type%20your%20problem/question%20here"));
×
368
    }
×
369

370
    /**
371
     * {@inheritDoc}
372
     */
373
    @Override
374
    public String getMountPath() {
375
        return MOUNT_PATH;
×
376
    }
377

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