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

knowledgepixels / nanodash / 17581065640

09 Sep 2025 11:22AM UTC coverage: 13.608% (-0.1%) from 13.73%
17581065640

push

github

ashleycaselli
chore: add error logging for exception handling in various components

406 of 3854 branches covered (10.53%)

Branch coverage included in aggregate %.

1072 of 7007 relevant lines covered (15.3%)

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 long serialVersionUID = 1L;
39
    private static final Logger logger = LoggerFactory.getLogger(GenOverviewPage.class);
×
40

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

46
    private ConnectorConfig config;
47

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

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

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

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

80
        try {
81

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

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

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

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

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

112
                    private static final long serialVersionUID = 1L;
113

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

126
                });
127

128
                c.add(new AjaxLink<>("allowncandidates") {
×
129

130
                    private static final long serialVersionUID = 1L;
131

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

145
                }.setVisible(fullList.size() > 10));
×
146

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

162
        try {
163
            final WebMarkupContainer c = new WebMarkupContainer("candidates-component");
×
164
            c.setOutputMarkupId(true);
×
165
            add(c);
×
166

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

178
            final List<ApiResponseEntry> listData = new ArrayList<ApiResponseEntry>();
×
179
            final ArrayList<ApiResponseEntry> fullList = new ArrayList<>();
×
180
            for (ApiResponseEntry a : resp.getData()) {
×
181
                if (listData.size() < 10) listData.add(a);
×
182
                // TODO This will become inefficient at some point:
183
                fullList.add(a);
×
184
            }
×
185

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

188
                private static final long serialVersionUID = 1L;
189

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

202
            });
203

204
            c.add(new AjaxLink<>("allcandidates") {
×
205

206
                private static final long serialVersionUID = 1L;
207

208
                @Override
209
                public void onClick(AjaxRequestTarget target) {
210
                    try {
211
                        listData.clear();
×
212
                        listData.addAll(fullList);
×
213
                        target.add(c);
×
214
                        setVisible(false);
×
215
                        target.add(this);
×
216
                    } catch (Exception ex) {
×
217
                        logger.error("Error in all candidates click", ex);
×
218
                    }
×
219
                }
×
220

221
            }.setVisible(fullList.size() > 10));
×
222

223
        } catch (Exception ex) {
×
224
            logger.error("Error in candidates section", ex);
×
225
        }
×
226

227
        if (getConfig().getAcceptedNanopubsApiCall() != null) {
×
228
            try {
229
                final WebMarkupContainer c = new WebMarkupContainer("accepted-component");
×
230
                c.setOutputMarkupId(true);
×
231
                add(c);
×
232

233
                ApiResponse resp = callApi(getConfig().getAcceptedNanopubsApiCall(), new HashMap<>());
×
234
                while (resp == null) {
×
235
                    // TODO Do this in an AJAX way:
236
                    try {
237
                        Thread.sleep(200);
×
238
                    } catch (InterruptedException ex) {
×
239
                        logger.error("Thread interrupted", ex);
×
240
                    }
×
241
                    resp = callApi(getConfig().getAcceptedNanopubsApiCall(), new HashMap<>());
×
242
                }
243

244
                final List<ApiResponseEntry> listData = new ArrayList<ApiResponseEntry>();
×
245
                final ArrayList<ApiResponseEntry> fullList = new ArrayList<>();
×
246
                for (ApiResponseEntry a : resp.getData()) {
×
247
                    if (listData.size() < 10) listData.add(a);
×
248
                    // TODO This will become inefficient at some point:
249
                    fullList.add(a);
×
250
                }
×
251

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

254
                    private static final long serialVersionUID = 1L;
255

256
                    @Override
257
                    protected void populateItem(Item<ApiResponseEntry> item) {
258
                        ApiResponseEntry e = item.getModelObject();
×
259
                        PageParameters params = new PageParameters().add("journal", journalId).add("id", e.get("np")).add("mode", "final");
×
260
                        BookmarkablePageLink<Void> l = new BookmarkablePageLink<Void>("acceptedlink", GenNanopubPage.class, params);
×
261
                        l.add(new Label("acceptedlinktext", "\"" + e.get("label") + "\""));
×
262
                        item.add(l);
×
263
                        IRI firstAuthorIri = Utils.vf.createIRI(e.get("firstAuthor"));
×
264

265
                        // TODO Move this user name extraction to a helper method:
266
                        String username;
267
                        if (User.getName(firstAuthorIri) != null) {
×
268
                            username = User.getShortDisplayName(firstAuthorIri);
×
269
                        } else {
270
                            try {
271
                                Nanopub np = Utils.getAsNanopub(e.get("np"));
×
272
                                username = Utils.getFoafNameMap(np).get(e.get("firstAuthor"));
×
273
                            } catch (Exception ex) {
×
274
                                logger.error("Error getting FOAF name for {} in {}", e.get("firstAuthor"), e.get("np"), ex);
×
275
                                username = User.getShortDisplayName(firstAuthorIri);
×
276
                            }
×
277
                        }
278

279
                        item.add(new Label("acceptednote", "by " + username + " on " + e.get("date").substring(0, 10)));
×
280
                    }
×
281

282
                });
283

284
                c.add(new AjaxLink<>("allaccepted") {
×
285

286
                    private static final long serialVersionUID = 1L;
287

288
                    @Override
289
                    public void onClick(AjaxRequestTarget target) {
290
                        try {
291
                            listData.clear();
×
292
                            listData.addAll(fullList);
×
293
                            target.add(c);
×
294
                            setVisible(false);
×
295
                            target.add(this);
×
296
                        } catch (Exception ex) {
×
297
                            logger.error("Error showing all accepted", ex);
×
298
                        }
×
299
                    }
×
300

301
                }.setVisible(fullList.size() > 10));
×
302

303
            } catch (Exception ex) {
×
304
                logger.error("Error in accepted section", ex);
×
305
            }
×
306
        }
307

308
        if (getConfig().getGeneralReactionsApiCall() != null) {
×
309
            try {
310
                final WebMarkupContainer c = new WebMarkupContainer("reactions-component");
×
311
                c.setOutputMarkupId(true);
×
312
                add(c);
×
313

314
                ApiResponse resp = callApi(getConfig().getGeneralReactionsApiCall(), new HashMap<>());
×
315
                while (resp == null) {
×
316
                    // TODO Do this in an AJAX way:
317
                    try {
318
                        Thread.sleep(200);
×
319
                    } catch (InterruptedException ex) {
×
320
                        logger.error("Thread interrupted", ex);
×
321
                    }
×
322
                    resp = callApi(getConfig().getGeneralReactionsApiCall(), new HashMap<>());
×
323
                }
324

325
                final List<ApiResponseEntry> listData = new ArrayList<ApiResponseEntry>();
×
326
                final ArrayList<ApiResponseEntry> fullList = new ArrayList<>();
×
327
                for (ApiResponseEntry a : resp.getData()) {
×
328
                    if (listData.size() < 10) listData.add(a);
×
329
                    // TODO This will become inefficient at some point:
330
                    fullList.add(a);
×
331
                }
×
332

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

335
                    private static final long serialVersionUID = 1L;
336

337
                    @Override
338
                    protected void populateItem(Item<ApiResponseEntry> item) {
339
                        ApiResponseEntry e = item.getModelObject();
×
340
                        PageParameters params = new PageParameters().add("journal", journalId).add("id", e.get("ref_np")).add("mode", "candidate");
×
341
                        BookmarkablePageLink<Void> l = new BookmarkablePageLink<Void>("reactionlink", GenNanopubPage.class, params);
×
342
                        l.add(new Label("reactionlinktext", "\"" + e.get("comment") + "\""));
×
343
                        item.add(l);
×
344
                        String pubkeyhash = Utils.createSha256HexHash(e.get("pubkey"));
×
345
                        String username = User.getShortDisplayNameForPubkeyhash(null, pubkeyhash);
×
346
                        item.add(new Label("reactionnote", "by " + username + " on " + e.get("date").substring(0, 10)));
×
347
                    }
×
348

349
                });
350

351
                c.add(new AjaxLink<>("allreactions") {
×
352

353
                    private static final long serialVersionUID = 1L;
354

355
                    @Override
356
                    public void onClick(AjaxRequestTarget target) {
357
                        try {
358
                            listData.clear();
×
359
                            listData.addAll(fullList);
×
360
                            target.add(c);
×
361
                            setVisible(false);
×
362
                            target.add(this);
×
363
                        } catch (Exception ex) {
×
364
                            logger.error("Error showing all reactions", ex);
×
365
                        }
×
366
                    }
×
367

368
                }.setVisible(fullList.size() > 10));
×
369

370
            } catch (Exception ex) {
×
371
                logger.error("Error in reactions section", ex);
×
372
            }
×
373
        }
374

375
        add(new Label("pagetitle", config.getJournalName() + " | nanodash"));
×
376
        add(new Label("journal-name-title", config.getJournalName()));
×
377
        add(new ExternalLink("journal-link", config.getJournalUrl(), config.getJournalName()));
×
378
        add(new Label("extra-instructions", config.getExtraInstructions()).setEscapeModelStrings(false));
×
379

380
        if (getConfig().getGeneralReactionsApiCall() == null) {
×
381
            // TODO Fix this in OverviewPage code once refactoring is finished:
382
            add(new Label("reactions-component").setVisible(false));
×
383
        }
384
        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"));
×
385
    }
×
386

387
    /**
388
     * {@inheritDoc}
389
     */
390
    @Override
391
    public String getMountPath() {
392
        return MOUNT_PATH;
×
393
    }
394

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