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

knowledgepixels / nanodash / 17211438187

25 Aug 2025 02:13PM UTC coverage: 12.474% (+0.03%) from 12.446%
17211438187

push

github

ashleycaselli
build(deps): update org.apache.maven.plugins:maven-compiler-plugin to v3.14.0

330 of 3766 branches covered (8.76%)

Branch coverage included in aggregate %.

982 of 6752 relevant lines covered (14.54%)

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

3
import com.knowledgepixels.nanodash.*;
4
import com.knowledgepixels.nanodash.page.ExplorePage;
5
import com.knowledgepixels.nanodash.page.NanodashPage;
6
import com.knowledgepixels.nanodash.template.*;
7
import org.apache.commons.lang3.StringUtils;
8
import org.apache.wicket.Component;
9
import org.apache.wicket.RestartResponseException;
10
import org.apache.wicket.ajax.AjaxEventBehavior;
11
import org.apache.wicket.ajax.AjaxRequestTarget;
12
import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
13
import org.apache.wicket.feedback.FeedbackMessage;
14
import org.apache.wicket.markup.html.WebMarkupContainer;
15
import org.apache.wicket.markup.html.WebPage;
16
import org.apache.wicket.markup.html.basic.Label;
17
import org.apache.wicket.markup.html.form.CheckBox;
18
import org.apache.wicket.markup.html.form.Form;
19
import org.apache.wicket.markup.html.form.FormComponent;
20
import org.apache.wicket.markup.html.link.BookmarkablePageLink;
21
import org.apache.wicket.markup.html.list.ListItem;
22
import org.apache.wicket.markup.html.list.ListView;
23
import org.apache.wicket.markup.html.panel.FeedbackPanel;
24
import org.apache.wicket.markup.html.panel.Panel;
25
import org.apache.wicket.markup.repeater.Item;
26
import org.apache.wicket.markup.repeater.data.DataView;
27
import org.apache.wicket.markup.repeater.data.ListDataProvider;
28
import org.apache.wicket.model.IModel;
29
import org.apache.wicket.model.Model;
30
import org.apache.wicket.request.mapper.parameter.PageParameters;
31
import org.apache.wicket.validation.IValidatable;
32
import org.apache.wicket.validation.IValidator;
33
import org.apache.wicket.validation.ValidationError;
34
import org.eclipse.rdf4j.model.IRI;
35
import org.eclipse.rdf4j.model.Literal;
36
import org.eclipse.rdf4j.model.Statement;
37
import org.eclipse.rdf4j.model.ValueFactory;
38
import org.eclipse.rdf4j.model.impl.SimpleValueFactory;
39
import org.eclipse.rdf4j.model.vocabulary.FOAF;
40
import org.eclipse.rdf4j.model.vocabulary.RDFS;
41
import org.nanopub.MalformedNanopubException;
42
import org.nanopub.Nanopub;
43
import org.nanopub.NanopubCreator;
44
import org.nanopub.NanopubUtils;
45
import org.nanopub.extra.security.SignNanopub;
46
import org.nanopub.extra.security.SignatureAlgorithm;
47
import org.nanopub.extra.security.TransformContext;
48
import org.nanopub.extra.server.PublishNanopub;
49
import org.nanopub.extra.services.ApiResponseEntry;
50
import org.slf4j.Logger;
51
import org.slf4j.LoggerFactory;
52
import org.wicketstuff.select2.ChoiceProvider;
53
import org.wicketstuff.select2.Response;
54
import org.wicketstuff.select2.Select2Choice;
55

56
import java.lang.reflect.InvocationTargetException;
57
import java.util.*;
58

59
/**
60
 * Form for publishing a nanopublication.
61
 */
62
public class PublishForm extends Panel {
63

64
    private static final long serialVersionUID = 1L;
65
    private static final Logger logger = LoggerFactory.getLogger(PublishForm.class);
×
66

67
    private static ValueFactory vf = SimpleValueFactory.getInstance();
×
68

69
    private static String creatorPubinfoTemplateId = "https://w3id.org/np/RAukAcWHRDlkqxk7H2XNSegc1WnHI569INvNr-xdptDGI";
×
70
    private static String licensePubinfoTempalteId = "https://w3id.org/np/RA0J4vUn_dekg-U1kK3AOEt02p9mT2WO03uGxLDec1jLw";
×
71
    private static String defaultProvTemplateId = "https://w3id.org/np/RA7lSq6MuK_TIC6JMSHvLtee3lpLoZDOqLJCLXevnrPoU";
×
72
    private static String supersedesPubinfoTemplateId = "https://w3id.org/np/RAoTD7udB2KtUuOuAe74tJi1t3VzK0DyWS7rYVAq1GRvw";
×
73
    private static String derivesFromPubinfoTemplateId = "https://w3id.org/np/RARW4MsFkHuwjycNElvEVtuMjpf4yWDL10-0C5l2MqqRQ";
×
74

75
    private static String[] fixedPubInfoTemplates = new String[]{creatorPubinfoTemplateId, licensePubinfoTempalteId};
×
76

77
    /**
78
     * Fill modes for the nanopublication to be created.
79
     */
80
    public enum FillMode {USE, SUPERSEDE, DERIVE}
×
81

82
    protected Form<?> form;
83
    protected FeedbackPanel feedbackPanel;
84
    private final TemplateContext assertionContext;
85
    private TemplateContext provenanceContext;
86
    private List<TemplateContext> pubInfoContexts = new ArrayList<>();
×
87
    private Map<String, TemplateContext> pubInfoContextMap = new HashMap<>();
×
88
    private List<TemplateContext> requiredPubInfoContexts = new ArrayList<>();
×
89
    private String targetNamespace;
90
    private Class<? extends WebPage> confirmPageClass;
91

92
    /**
93
     * Constructor for the PublishForm.
94
     *
95
     * @param id               the Wicket component ID
96
     * @param pageParams       the parameters for the page, which may include information on how to fill the form
97
     * @param publishPageClass the class of the page to redirect to after successful publication
98
     * @param confirmPageClass the class of the confirmation page to show after publication
99
     */
100
    public PublishForm(String id, final PageParameters pageParams, Class<? extends WebPage> publishPageClass, Class<? extends WebPage> confirmPageClass) {
101
        super(id);
×
102
        setOutputMarkupId(true);
×
103
        this.confirmPageClass = confirmPageClass;
×
104

105
        WebMarkupContainer linkMessageItem = new WebMarkupContainer("link-message-item");
×
106
        if (pageParams.get("link-message").isNull()) {
×
107
            linkMessageItem.add(new Label("link-message", ""));
×
108
            linkMessageItem.setVisible(false);
×
109
        } else {
110
            linkMessageItem.add(new Label("link-message", Utils.sanitizeHtml(pageParams.get("link-message").toString())).setEscapeModelStrings(false));
×
111
        }
112
        add(linkMessageItem);
×
113

114
        final Nanopub fillNp;
115
        final FillMode fillMode;
116
        boolean fillOnlyAssertion = false;
×
117
        if (!pageParams.get("use").isNull()) {
×
118
            fillNp = Utils.getNanopub(pageParams.get("use").toString());
×
119
            fillMode = FillMode.USE;
×
120
        } else if (!pageParams.get("use-a").isNull()) {
×
121
            fillNp = Utils.getNanopub(pageParams.get("use-a").toString());
×
122
            fillMode = FillMode.USE;
×
123
            fillOnlyAssertion = true;
×
124
        } else if (!pageParams.get("supersede").isNull()) {
×
125
            fillNp = Utils.getNanopub(pageParams.get("supersede").toString());
×
126
            fillMode = FillMode.SUPERSEDE;
×
127
            targetNamespace = pageParams.get("supersede").toString().replaceFirst("RA[A-Za-z0-9-_]{43}$", "");
×
128
        } else if (!pageParams.get("supersede-a").isNull()) {
×
129
            fillNp = Utils.getNanopub(pageParams.get("supersede-a").toString());
×
130
            fillMode = FillMode.SUPERSEDE;
×
131
            fillOnlyAssertion = true;
×
132
        } else if (!pageParams.get("derive").isNull()) {
×
133
            fillNp = Utils.getNanopub(pageParams.get("derive").toString());
×
134
            fillMode = FillMode.DERIVE;
×
135
        } else if (!pageParams.get("derive-a").isNull()) {
×
136
            fillNp = Utils.getNanopub(pageParams.get("derive-a").toString());
×
137
            fillMode = FillMode.DERIVE;
×
138
            fillOnlyAssertion = true;
×
139
        } else if (!pageParams.get("fill-all").isNull()) {
×
140
            // TODO: This is deprecated and should be removed at some point
141
            fillNp = Utils.getNanopub(pageParams.get("fill-all").toString());
×
142
            fillMode = FillMode.USE;
×
143
        } else if (!pageParams.get("fill").isNull()) {
×
144
            // TODO: This is deprecated and should be removed at some point
145
            fillNp = Utils.getNanopub(pageParams.get("fill").toString());
×
146
            fillMode = FillMode.SUPERSEDE;
×
147
        } else {
148
            fillNp = null;
×
149
            fillMode = null;
×
150
        }
151

152
        final TemplateData td = TemplateData.get();
×
153

154
        // TODO Properly integrate this namespace feature:
155
        String templateId = pageParams.get("template").toString();
×
156
        if (td.getTemplate(templateId).getTargetNamespace() != null) {
×
157
            targetNamespace = td.getTemplate(templateId).getTargetNamespace();
×
158
        }
159
        if (!pageParams.get("target-namespace").isNull()) {
×
160
            targetNamespace = pageParams.get("target-namespace").toString();
×
161
        }
162
        if (targetNamespace == null) {
×
163
            targetNamespace = Template.DEFAULT_TARGET_NAMESPACE;
×
164
        }
165
        String targetNamespaceLabel = targetNamespace + "...";
×
166
        targetNamespace = targetNamespace + "ARTIFACTCODE-PLACEHOLDER/";
×
167

168
        assertionContext = new TemplateContext(ContextType.ASSERTION, templateId, "statement", targetNamespace);
×
169
        assertionContext.setFillMode(fillMode);
×
170
        final String prTemplateId;
171
        if (pageParams.get("prtemplate").toString() != null) {
×
172
            prTemplateId = pageParams.get("prtemplate").toString();
×
173
        } else {
174
            if (fillNp != null && !fillOnlyAssertion) {
×
175
                if (td.getProvenanceTemplateId(fillNp) != null) {
×
176
                    prTemplateId = td.getProvenanceTemplateId(fillNp).stringValue();
×
177
                } else {
178
                    prTemplateId = "http://purl.org/np/RAcm8OurwUk15WOgBM9wySo-T3a5h6as4K8YR5MBrrxUc";
×
179
                }
180
            } else if (assertionContext.getTemplate().getDefaultProvenance() != null) {
×
181
                prTemplateId = assertionContext.getTemplate().getDefaultProvenance().stringValue();
×
182
            } else {
183
                prTemplateId = defaultProvTemplateId;
×
184
            }
185
        }
186
        provenanceContext = new TemplateContext(ContextType.PROVENANCE, prTemplateId, "pr-statement", targetNamespace);
×
187
        for (String t : fixedPubInfoTemplates) {
×
188
            // TODO consistently check for latest versions of templates here and below:
189
            TemplateContext c = new TemplateContext(ContextType.PUBINFO, t, "pi-statement", targetNamespace);
×
190
            pubInfoContexts.add(c);
×
191
            pubInfoContextMap.put(c.getTemplate().getId(), c);
×
192
            requiredPubInfoContexts.add(c);
×
193
        }
194
        if (fillMode == FillMode.SUPERSEDE) {
×
195
            TemplateContext c = new TemplateContext(ContextType.PUBINFO, supersedesPubinfoTemplateId, "pi-statement", targetNamespace);
×
196
            pubInfoContexts.add(c);
×
197
            pubInfoContextMap.put(supersedesPubinfoTemplateId, c);
×
198
            //requiredPubInfoContexts.add(c);
199
            c.setParam("np", fillNp.getUri().stringValue());
×
200
        } else if (fillMode == FillMode.DERIVE) {
×
201
            TemplateContext c = new TemplateContext(ContextType.PUBINFO, derivesFromPubinfoTemplateId, "pi-statement", targetNamespace);
×
202
            pubInfoContexts.add(c);
×
203
            pubInfoContextMap.put(derivesFromPubinfoTemplateId, c);
×
204
            c.setParam("np", fillNp.getUri().stringValue());
×
205
        }
206
        for (IRI r : assertionContext.getTemplate().getRequiredPubinfoElements()) {
×
207
            String latestId = QueryApiAccess.getLatestVersionId(r.stringValue());
×
208
            if (pubInfoContextMap.containsKey(r.stringValue()) || pubInfoContextMap.containsKey(latestId)) continue;
×
209
            TemplateContext c = new TemplateContext(ContextType.PUBINFO, r.stringValue(), "pi-statement", targetNamespace);
×
210
            pubInfoContexts.add(c);
×
211
            pubInfoContextMap.put(c.getTemplateId(), c);
×
212
            requiredPubInfoContexts.add(c);
×
213
        }
×
214
        Map<Integer, TemplateContext> piParamIdMap = new HashMap<>();
×
215
        for (String k : pageParams.getNamedKeys()) {
×
216
            if (!k.matches("pitemplate[1-9][0-9]*")) continue;
×
217
            Integer i = Integer.parseInt(k.replaceFirst("^pitemplate([1-9][0-9]*)$", "$1"));
×
218
            String tid = pageParams.get(k).toString();
×
219
            // TODO Allow for automatically using latest template version:
220
            //String piTempalteIdLatest = QueryApiAccess.getLatestVersionId(tid);
221
            TemplateContext c = createPubinfoContext(tid);
×
222
            if (piParamIdMap.containsKey(i)) {
×
223
                // TODO: handle this error better
224
                logger.error("ERROR: pitemplate param identifier assigned multiple times: " + i);
×
225
            }
226
            piParamIdMap.put(i, c);
×
227
        }
×
228
        if (fillNp != null && !fillOnlyAssertion) {
×
229
            for (IRI piTemplateId : td.getPubinfoTemplateIds(fillNp)) {
×
230
                String piTempalteIdLatest = QueryApiAccess.getLatestVersionId(piTemplateId.stringValue());
×
231
                if (piTempalteIdLatest.equals(supersedesPubinfoTemplateId)) continue;
×
232
                if (!pubInfoContextMap.containsKey(piTempalteIdLatest)) {
×
233
                    // TODO Allow for automatically using latest template version
234
                    createPubinfoContext(piTemplateId.stringValue());
×
235
                }
236
            }
×
237
        }
238
        for (String k : pageParams.getNamedKeys()) {
×
239
            if (k.startsWith("param_")) assertionContext.setParam(k.substring(6), pageParams.get(k).toString());
×
240
            if (k.startsWith("prparam_")) provenanceContext.setParam(k.substring(8), pageParams.get(k).toString());
×
241
            if (k.matches("piparam[1-9][0-9]*_.*")) {
×
242
                Integer i = Integer.parseInt(k.replaceFirst("^piparam([1-9][0-9]*)_.*$", "$1"));
×
243
                if (!piParamIdMap.containsKey(i)) {
×
244
                    // TODO: handle this error better
245
                    logger.error("ERROR: pitemplate param identifier not found: " + i);
×
246
                    continue;
×
247
                }
248
                String n = k.replaceFirst("^piparam[1-9][0-9]*_(.*)$", "$1");
×
249
                logger.info(n);
×
250
                piParamIdMap.get(i).setParam(n, pageParams.get(k).toString());
×
251
            }
252
        }
×
253

254
        // Init statements only now, in order to pick up parameter values:
255
        assertionContext.initStatements();
×
256
        provenanceContext.initStatements();
×
257
        for (TemplateContext c : pubInfoContexts) {
×
258
            c.initStatements();
×
259
        }
×
260

261
        String latestAssertionId = QueryApiAccess.getLatestVersionId(assertionContext.getTemplateId());
×
262
        if (!assertionContext.getTemplateId().equals(latestAssertionId)) {
×
263
            add(new Label("newversion", "There is a new version of this assertion template:"));
×
264
            PageParameters params = new PageParameters(pageParams);
×
265
            params.set("template", latestAssertionId).remove("formobj");
×
266
            add(new BookmarkablePageLink<Void>("newversionlink", publishPageClass, params));
×
267
            if ("latest".equals(pageParams.get("template-version").toString())) {
×
268
                throw new RestartResponseException(publishPageClass, params);
×
269
            }
270
        } else {
×
271
            add(new Label("newversion", "").setVisible(false));
×
272
            add(new Label("newversionlink", "").setVisible(false));
×
273
        }
274

275
        final Nanopub improveNp;
276
        if (!pageParams.get("improve").isNull()) {
×
277
            improveNp = Utils.getNanopub(pageParams.get("improve").toString());
×
278
        } else {
279
            improveNp = null;
×
280
        }
281

282
        final List<Statement> unusedStatementList = new ArrayList<>();
×
283
        final List<Statement> unusedPrStatementList = new ArrayList<>();
×
284
        final List<Statement> unusedPiStatementList = new ArrayList<>();
×
285
        if (fillNp != null) {
×
286
            ValueFiller filler = new ValueFiller(fillNp, ContextType.ASSERTION, true, fillMode);
×
287
            filler.fill(assertionContext);
×
288
            unusedStatementList.addAll(filler.getUnusedStatements());
×
289

290
            if (!fillOnlyAssertion) {
×
291
                ValueFiller prFiller = new ValueFiller(fillNp, ContextType.PROVENANCE, true);
×
292
                prFiller.fill(provenanceContext);
×
293
                unusedPrStatementList.addAll(prFiller.getUnusedStatements());
×
294

295
                ValueFiller piFiller = new ValueFiller(fillNp, ContextType.PUBINFO, true);
×
296
                if (!assertionContext.getTemplate().getTargetNanopubTypes().isEmpty()) {
×
297
                    for (Statement st : new ArrayList<>(piFiller.getUnusedStatements())) {
×
298
                        if (st.getSubject().stringValue().equals("local:nanopub") && st.getPredicate().equals(NanopubUtils.HAS_NANOPUB_TYPE)) {
×
299
                            if (assertionContext.getTemplate().getTargetNanopubTypes().contains(st.getObject())) {
×
300
                                piFiller.removeUnusedStatement(st);
×
301
                            }
302
                        }
303
                    }
×
304
                }
305
                for (TemplateContext c : pubInfoContexts) {
×
306
                    piFiller.fill(c);
×
307
                }
×
308
                piFiller.removeUnusedStatements(NanodashSession.get().getUserIri(), FOAF.NAME, null);
×
309
                if (piFiller.hasUnusedStatements()) {
×
310
                    final String handcodedStatementsTemplateId = "https://w3id.org/np/RAMEgudZsQ1bh1fZhfYnkthqH6YSXpghSE_DEN1I-6eAI";
×
311
                    if (!pubInfoContextMap.containsKey(handcodedStatementsTemplateId)) {
×
312
                        TemplateContext c = createPubinfoContext(handcodedStatementsTemplateId);
×
313
                        c.initStatements();
×
314
                        piFiller.fill(c);
×
315
                    }
316
                }
317
                unusedPiStatementList.addAll(piFiller.getUnusedStatements());
×
318
                // TODO: Also use pubinfo templates stated in nanopub to be filled in?
319
//                                Set<IRI> pubinfoTemplateIds = Template.getPubinfoTemplateIds(fillNp);
320
//                                if (!pubinfoTemplateIds.isEmpty()) {
321
//                                        ValueFiller piFiller = new ValueFiller(fillNp, ContextType.PUBINFO);
322
//                                        for (IRI pubinfoTemplateId : pubinfoTemplateIds) {
323
//                                                // TODO: Make smart choice on the ordering in trying to fill in all pubinfo elements
324
//                                                piFiller.fill(pubInfoContextMap.get(pubinfoTemplateId.stringValue()));
325
//                                        }
326
//                                        warningMessage += (piFiller.getWarningMessage() == null ? "" : "Publication info: " + piFiller.getWarningMessage() + " ");
327
//                                }
328
            }
329
        } else if (improveNp != null) {
×
330
            ValueFiller filler = new ValueFiller(improveNp, ContextType.ASSERTION, true);
×
331
            filler.fill(assertionContext);
×
332
            unusedStatementList.addAll(filler.getUnusedStatements());
×
333
        }
334
        if (!unusedStatementList.isEmpty()) {
×
335
            add(new Label("warnings", "Some content from the existing nanopublication could not be filled in:"));
×
336
        } else {
337
            add(new Label("warnings", "").setVisible(false));
×
338
        }
339
        add(new DataView<Statement>("unused-statements", new ListDataProvider<Statement>(unusedStatementList)) {
×
340

341
            private static final long serialVersionUID = 1L;
342

343
            @Override
344
            protected void populateItem(Item<Statement> item) {
345
                item.add(new TripleItem("unused-statement", item.getModelObject(), (fillNp != null ? fillNp : improveNp), null));
×
346
            }
×
347

348
        });
349
        add(new DataView<Statement>("unused-prstatements", new ListDataProvider<Statement>(unusedPrStatementList)) {
×
350

351
            private static final long serialVersionUID = 1L;
352

353
            @Override
354
            protected void populateItem(Item<Statement> item) {
355
                item.add(new TripleItem("unused-prstatement", item.getModelObject(), (fillNp != null ? fillNp : improveNp), null));
×
356
            }
×
357

358
        });
359
        add(new DataView<Statement>("unused-pistatements", new ListDataProvider<Statement>(unusedPiStatementList)) {
×
360

361
            private static final long serialVersionUID = 1L;
362

363
            @Override
364
            protected void populateItem(Item<Statement> item) {
365
                item.add(new TripleItem("unused-pistatement", item.getModelObject(), (fillNp != null ? fillNp : improveNp), null));
×
366
            }
×
367

368
        });
369

370
        // Finalize statements, which picks up parameter values in repetitions:
371
        assertionContext.finalizeStatements();
×
372
        provenanceContext.finalizeStatements();
×
373
        for (TemplateContext c : pubInfoContexts) {
×
374
            c.finalizeStatements();
×
375
        }
×
376

377
        final CheckBox consentCheck = new CheckBox("consentcheck", new Model<>(false));
×
378
        consentCheck.setRequired(true);
×
379
        consentCheck.add(new InvalidityHighlighting());
×
380
        consentCheck.add(new IValidator<Boolean>() {
×
381

382
            private static final long serialVersionUID = 1L;
383

384
            @Override
385
            public void validate(IValidatable<Boolean> validatable) {
386
                if (!Boolean.TRUE.equals(validatable.getValue())) {
×
387
                    validatable.error(new ValidationError("You need to check the checkbox that you understand the consequences."));
×
388
                }
389
            }
×
390

391
        });
392

393
        form = new Form<Void>("form") {
×
394

395
            private static final long serialVersionUID = 1L;
396

397
            @Override
398
            protected void onConfigure() {
399
                super.onConfigure();
×
400
                form.getFeedbackMessages().clear();
×
401
//                                formComponents.clear();
402
            }
×
403

404
            protected void onSubmit() {
405
                logger.info("Publish form submitted");
×
406
                Nanopub signedNp = null;
×
407
                try {
408
                    Nanopub np = createNanopub();
×
409
                    logger.info("Nanopublication created: " + np.getUri());
×
410
                    TransformContext tc = new TransformContext(SignatureAlgorithm.RSA, NanodashSession.get().getKeyPair(), NanodashSession.get().getUserIri(), false, false, false);
×
411
                    signedNp = SignNanopub.signAndTransform(np, tc);
×
412
                    logger.info("Nanopublication signed: " + signedNp.getUri());
×
413
                    String npUrl = PublishNanopub.publish(signedNp);
×
414
                    logger.info("Nanopublication published: " + npUrl);
×
415
                } catch (Exception ex) {
×
416
                    signedNp = null;
×
417
                    ex.printStackTrace();
×
418
                    String message = ex.getClass().getName();
×
419
                    if (ex.getMessage() != null) message = ex.getMessage();
×
420
                    feedbackPanel.error(message);
×
421
                }
×
422
                if (signedNp != null) {
×
423
                    throw new RestartResponseException(getConfirmPage(signedNp, pageParams));
×
424
                } else {
425
                    logger.error("Nanopublication publishing failed");
×
426
                }
427
            }
×
428

429
            @Override
430
            protected void onValidate() {
431
                super.onValidate();
×
432
                for (Component fc : assertionContext.getComponents()) {
×
433
                    processFeedback(fc);
×
434
                }
×
435
                for (Component fc : provenanceContext.getComponents()) {
×
436
                    processFeedback(fc);
×
437
                }
×
438
                for (TemplateContext c : pubInfoContexts) {
×
439
                    for (Component fc : c.getComponents()) {
×
440
                        processFeedback(fc);
×
441
                    }
×
442
                }
×
443
            }
×
444

445
            private void processFeedback(Component c) {
446
                if (c instanceof FormComponent) {
×
447
                    ((FormComponent<?>) c).processInput();
×
448
                }
449
                for (FeedbackMessage fm : c.getFeedbackMessages()) {
×
450
                    form.getFeedbackMessages().add(fm);
×
451
                }
×
452
            }
×
453

454
        };
455
        form.setOutputMarkupId(true);
×
456

457
        form.add(new Label("nanopub-namespace", targetNamespaceLabel));
×
458

459
        form.add(new BookmarkablePageLink<Void>("templatelink", ExplorePage.class, new PageParameters().add("id", assertionContext.getTemplate().getId())));
×
460
        form.add(new Label("templatename", assertionContext.getTemplate().getLabel()));
×
461
        String description = assertionContext.getTemplate().getLabel();
×
462
        if (description == null) description = "";
×
463
        form.add(new Label("templatedesc", assertionContext.getTemplate().getDescription()).setEscapeModelStrings(false));
×
464

465
        form.add(new ListView<StatementItem>("statements", assertionContext.getStatementItems()) {
×
466

467
            private static final long serialVersionUID = 1L;
468

469
            protected void populateItem(ListItem<StatementItem> item) {
470
                item.add(item.getModelObject());
×
471
            }
×
472

473
        });
474

475
        final Map<String, Boolean> handledProvTemplates = new HashMap<>();
×
476
        final String defaultProvTemplateId;
477
        if (assertionContext.getTemplate().getDefaultProvenance() != null) {
×
478
            defaultProvTemplateId = assertionContext.getTemplate().getDefaultProvenance().stringValue();
×
479
            handledProvTemplates.put(defaultProvTemplateId, true);
×
480
        } else {
481
            defaultProvTemplateId = null;
×
482
        }
483
        final List<String> recommendedProvTemplateOptionIds = new ArrayList<>();
×
484
        final List<String> provTemplateOptionIds = new ArrayList<>();
×
485
        if (pageParams.get("prtemplate-options").isNull()) {
×
486
            // TODO Make this dynamic and consider updated templates:
487
            recommendedProvTemplateOptionIds.add("https://w3id.org/np/RA7lSq6MuK_TIC6JMSHvLtee3lpLoZDOqLJCLXevnrPoU");
×
488
            recommendedProvTemplateOptionIds.add("http://purl.org/np/RAcTpoh5Ra0ssqmcpOgWdaZ_YiPE6demO6cpw-2RvSNs8");
×
489
            recommendedProvTemplateOptionIds.add("http://purl.org/np/RA4LGtuOqTIMqVAkjnfBXk1YDcAPNadP5CGiaJiBkdHCQ");
×
490
            recommendedProvTemplateOptionIds.add("http://purl.org/np/RAl_-VTw9Re_uRF8r8y0rjlfnu7FlhTa8xg_8xkcweqiE");
×
491
            recommendedProvTemplateOptionIds.add("https://w3id.org/np/RASORV2mMEVpS4lWh2bwUTEcV-RWjbD9RPbN7J0PIeYAU");
×
492
            recommendedProvTemplateOptionIds.add("http://purl.org/np/RAjkBbM5yQm7hKH1l_Jk3HAUqWi3Bd57TPmAOZCsZmi_M");
×
493
            recommendedProvTemplateOptionIds.add("http://purl.org/np/RAGXx_k9eQMnXaCbsXMsJbGClwZtQEGNg0GVJu6amdAVw");
×
494
            recommendedProvTemplateOptionIds.add("http://purl.org/np/RA1fnITI3Pu1UQ0CHghNpys3JwQrM32LBnjmDLoayp9-4");
×
495
            recommendedProvTemplateOptionIds.add("http://purl.org/np/RAJgbsGeGdTG-zq_gU0TLw4s3raMgoRk-mPlc2DSLXvE0");
×
496
            recommendedProvTemplateOptionIds.add("http://purl.org/np/RA6SXfhUY-xeblZU8HhPddw6tsu-C5NXevG6C_zv4bMxU");
×
497
            for (String s : recommendedProvTemplateOptionIds) {
×
498
                handledProvTemplates.put(s, true);
×
499
            }
×
500

501
            for (ApiResponseEntry t : td.getProvenanceTemplates()) {
×
502
                String tid = t.get("np");
×
503
                if (handledProvTemplates.containsKey(tid)) continue;
×
504
                provTemplateOptionIds.add(tid);
×
505
                handledProvTemplates.put(tid, true);
×
506
            }
×
507
        } else {
508
            for (String s : pageParams.get("prtemplate-options").toString().split(" ")) {
×
509
                if (handledProvTemplates.containsKey(s)) continue;
×
510
                recommendedProvTemplateOptionIds.add(s);
×
511
                handledProvTemplates.put(s, true);
×
512
            }
513
        }
514

515
        ChoiceProvider<String> prTemplateChoiceProvider = new ChoiceProvider<String>() {
×
516

517
            private static final long serialVersionUID = 1L;
518

519
            @Override
520
            public String getDisplayValue(String object) {
521
                if (object == null || object.isEmpty()) return "";
×
522
                Template t = td.getTemplate(object);
×
523
                if (t != null) return t.getLabel();
×
524
                return object;
×
525
            }
526

527
            @Override
528
            public String getIdValue(String object) {
529
                return object;
×
530
            }
531

532
            // Getting strange errors with Tomcat if this method is not overridden:
533
            @Override
534
            public void detach() {
535
            }
×
536

537
            @Override
538
            public void query(String term, int page, Response<String> response) {
539
                if (term == null) term = "";
×
540
                term = term.toLowerCase();
×
541
                if (pageParams.get("prtemplate").toString() != null) {
×
542
                    // Using this work-around with "——" because 'optgroup' is not available through Wicket's Select2 classes
543
                    response.add("—— default for this link ——");
×
544
                    response.add(prTemplateId);
×
545
                }
546
                if (defaultProvTemplateId != null) {
×
547
                    response.add("—— default for this template ——");
×
548
                    response.add(defaultProvTemplateId);
×
549
                }
550
                if (!recommendedProvTemplateOptionIds.isEmpty()) {
×
551
                    if (pageParams.get("prtemplate-options").isNull()) {
×
552
                        response.add("—— recommended ——");
×
553
                    }
554
                    for (String s : recommendedProvTemplateOptionIds) {
×
555
                        if (s.toLowerCase().contains(term) || getDisplayValue(s).toLowerCase().contains(term)) {
×
556
                            response.add(s);
×
557
                        }
558
                    }
×
559
                }
560
                if (!provTemplateOptionIds.isEmpty()) {
×
561
                    response.add("—— others ——");
×
562
                    for (String s : provTemplateOptionIds) {
×
563
                        if (s.toLowerCase().contains(term) || getDisplayValue(s).toLowerCase().contains(term)) {
×
564
                            response.add(s);
×
565
                        }
566
                    }
×
567
                }
568
            }
×
569

570
            @Override
571
            public Collection<String> toChoices(Collection<String> ids) {
572
                return ids;
×
573
            }
574

575
        };
576
        final IModel<String> prTemplateModel = Model.of(provenanceContext.getTemplate().getId());
×
577
        Select2Choice<String> prTemplateChoice = new Select2Choice<String>("prtemplate", prTemplateModel, prTemplateChoiceProvider);
×
578
        prTemplateChoice.setRequired(true);
×
579
        prTemplateChoice.getSettings().setCloseOnSelect(true);
×
580
        prTemplateChoice.add(new AjaxFormComponentUpdatingBehavior("change") {
×
581

582
            private static final long serialVersionUID = 1L;
583

584
            @Override
585
            protected void onUpdate(AjaxRequestTarget target) {
586
                String o = prTemplateModel.getObject();
×
587
                if (o.startsWith("——")) {
×
588
                    o = provenanceContext.getTemplate().getId();
×
589
                    prTemplateModel.setObject(o);
×
590
                }
591
                provenanceContext = new TemplateContext(ContextType.PROVENANCE, prTemplateModel.getObject(), "pr-statement", targetNamespace);
×
592
                provenanceContext.initStatements();
×
593
                refreshProvenance(target);
×
594
                provenanceContext.finalizeStatements();
×
595
            }
×
596

597
        });
598
        form.add(prTemplateChoice);
×
599
        refreshProvenance(null);
×
600

601
        final Map<String, Boolean> handledPiTemplates = new HashMap<>();
×
602
        final List<String> recommendedPiTemplateOptionIds = new ArrayList<>();
×
603
        final List<String> piTemplateOptionIds = new ArrayList<>();
×
604
        // TODO Make this dynamic and consider updated templates:
605
        recommendedPiTemplateOptionIds.add("http://purl.org/np/RAXflINqt3smqxV5Aq7E9lzje4uLdkKIOefa6Bp8oJ8CY");
×
606
        recommendedPiTemplateOptionIds.add("https://w3id.org/np/RARW4MsFkHuwjycNElvEVtuMjpf4yWDL10-0C5l2MqqRQ");
×
607
        recommendedPiTemplateOptionIds.add("https://w3id.org/np/RA16U9Wo30ObhrK1NzH7EsmVRiRtvEuEA_Dfc-u8WkUCA");
×
608
        recommendedPiTemplateOptionIds.add("http://purl.org/np/RAdyqI6k07V5nAS82C6hvIDtNWk179EIV4DV-sLbOFKg4");
×
609
        recommendedPiTemplateOptionIds.add("https://w3id.org/np/RAjvEpLZUE7rMoa8q6mWSsN6utJDp-5FmgO47YGsbgw3w");
×
610
        recommendedPiTemplateOptionIds.add("http://purl.org/np/RAxuGRKID6yNg63V5Mf0ot2NjncOnodh-mkN3qT_1txGI");
×
611
        for (TemplateContext c : pubInfoContexts) {
×
612
            String s = c.getTemplate().getId();
×
613
            handledPiTemplates.put(s, true);
×
614
        }
×
615
        for (String s : recommendedPiTemplateOptionIds) {
×
616
            handledPiTemplates.put(s, true);
×
617
        }
×
618

619
        for (ApiResponseEntry entry : td.getPubInfoTemplates()) {
×
620
            String tid = entry.get("np");
×
621
            if (handledPiTemplates.containsKey(tid)) continue;
×
622
            piTemplateOptionIds.add(tid);
×
623
            handledPiTemplates.put(tid, true);
×
624
        }
×
625

626
        ChoiceProvider<String> piTemplateChoiceProvider = new ChoiceProvider<String>() {
×
627

628
            private static final long serialVersionUID = 1L;
629

630
            @Override
631
            public String getDisplayValue(String object) {
632
                if (object == null || object.isEmpty()) return "";
×
633
                Template t = td.getTemplate(object);
×
634
                if (t != null) return t.getLabel();
×
635
                return object;
×
636
            }
637

638
            @Override
639
            public String getIdValue(String object) {
640
                return object;
×
641
            }
642

643
            // Getting strange errors with Tomcat if this method is not overridden:
644
            @Override
645
            public void detach() {
646
            }
×
647

648
            @Override
649
            public void query(String term, int page, Response<String> response) {
650
                if (term == null) term = "";
×
651
                term = term.toLowerCase();
×
652
                if (!recommendedPiTemplateOptionIds.isEmpty()) {
×
653
                    response.add("—— recommended ——");
×
654
                    for (String s : recommendedPiTemplateOptionIds) {
×
655
                        boolean isAlreadyUsed = false;
×
656
                        for (TemplateContext c : pubInfoContexts) {
×
657
                            // TODO: make this more efficient/nicer
658
                            if (c.getTemplate().getId().equals(s)) {
×
659
                                isAlreadyUsed = true;
×
660
                                break;
×
661
                            }
662
                        }
×
663
                        if (isAlreadyUsed) continue;
×
664
                        if (s.toLowerCase().contains(term) || getDisplayValue(s).toLowerCase().contains(term)) {
×
665
                            response.add(s);
×
666
                        }
667
                    }
×
668
                }
669
                if (!piTemplateOptionIds.isEmpty()) {
×
670
                    response.add("—— others ——");
×
671
                    for (String s : piTemplateOptionIds) {
×
672
                        boolean isAlreadyUsed = false;
×
673
                        for (TemplateContext c : pubInfoContexts) {
×
674
                            // TODO: make this more efficient/nicer
675
                            if (c.getTemplate().getId().equals(s)) {
×
676
                                isAlreadyUsed = true;
×
677
                                break;
×
678
                            }
679
                        }
×
680
                        if (isAlreadyUsed) continue;
×
681
                        if (s.toLowerCase().contains(term) || getDisplayValue(s).toLowerCase().contains(term)) {
×
682
                            response.add(s);
×
683
                        }
684
                    }
×
685
                }
686
            }
×
687

688
            @Override
689
            public Collection<String> toChoices(Collection<String> ids) {
690
                return ids;
×
691
            }
692

693
        };
694
        final IModel<String> newPiTemplateModel = Model.of();
×
695
        Select2Choice<String> piTemplateChoice = new Select2Choice<String>("pitemplate", newPiTemplateModel, piTemplateChoiceProvider);
×
696
        piTemplateChoice.getSettings().setCloseOnSelect(true);
×
697
        piTemplateChoice.getSettings().setPlaceholder("add element...");
×
698
        piTemplateChoice.add(new AjaxFormComponentUpdatingBehavior("change") {
×
699

700
            private static final long serialVersionUID = 1L;
701

702
            @Override
703
            protected void onUpdate(AjaxRequestTarget target) {
704
                if (newPiTemplateModel.getObject().startsWith("——")) {
×
705
                    newPiTemplateModel.setObject(null);
×
706
                    refreshPubInfo(target);
×
707
                    return;
×
708
                }
709
                String id = newPiTemplateModel.getObject();
×
710
                TemplateContext c = new TemplateContext(ContextType.PUBINFO, id, "pi-statement", targetNamespace);
×
711
                c.initStatements();
×
712
                pubInfoContexts.add(c);
×
713
                newPiTemplateModel.setObject(null);
×
714
                refreshPubInfo(target);
×
715
                c.finalizeStatements();
×
716
            }
×
717

718
        });
719
        form.add(piTemplateChoice);
×
720
        refreshPubInfo(null);
×
721

722
        form.add(consentCheck);
×
723
        add(form);
×
724

725
        feedbackPanel = new FeedbackPanel("feedback");
×
726
        feedbackPanel.setOutputMarkupId(true);
×
727
        add(feedbackPanel);
×
728
    }
×
729

730
    private void refreshProvenance(AjaxRequestTarget target) {
731
        if (target != null) {
×
732
            form.remove("prtemplatelink");
×
733
            form.remove("pr-statements");
×
734
            target.add(form);
×
735
            target.appendJavaScript("updateElements();");
×
736
        }
737
        form.add(new BookmarkablePageLink<Void>("prtemplatelink", ExplorePage.class, new PageParameters().add("id", provenanceContext.getTemplate().getId())));
×
738
        ListView<StatementItem> list = new ListView<StatementItem>("pr-statements", provenanceContext.getStatementItems()) {
×
739

740
            private static final long serialVersionUID = 1L;
741

742
            protected void populateItem(ListItem<StatementItem> item) {
743
                item.add(item.getModelObject());
×
744
            }
×
745

746
        };
747
        list.setOutputMarkupId(true);
×
748
        form.add(list);
×
749
    }
×
750

751
    private void refreshPubInfo(AjaxRequestTarget target) {
752
        ListView<TemplateContext> list = new ListView<TemplateContext>("pis", pubInfoContexts) {
×
753

754
            private static final long serialVersionUID = 1L;
755

756
            protected void populateItem(ListItem<TemplateContext> item) {
757
                final TemplateContext pic = item.getModelObject();
×
758
                item.add(new Label("pitemplatename", pic.getTemplate().getLabel()));
×
759
                item.add(new BookmarkablePageLink<Void>("pitemplatelink", ExplorePage.class, new PageParameters().add("id", pic.getTemplate().getId())));
×
760
                Label remove = new Label("piremove", "×");
×
761
                item.add(remove);
×
762
                remove.add(new AjaxEventBehavior("click") {
×
763
                    private static final long serialVersionUID = 1L;
764

765
                    @Override
766
                    protected void onEvent(AjaxRequestTarget target) {
767
                        pubInfoContexts.remove(pic);
×
768
                        target.add(PublishForm.this);
×
769
                        target.appendJavaScript("updateElements();");
×
770
                    }
×
771
                });
772
                if (requiredPubInfoContexts.contains(pic)) remove.setVisible(false);
×
773
                item.add(new ListView<StatementItem>("pi-statements", pic.getStatementItems()) {
×
774

775
                    private static final long serialVersionUID = 1L;
776

777
                    protected void populateItem(ListItem<StatementItem> item) {
778
                        item.add(item.getModelObject());
×
779
                    }
×
780

781
                });
782
            }
×
783

784
        };
785
        list.setOutputMarkupId(true);
×
786
        if (target == null) {
×
787
            form.add(list);
×
788
        } else {
789
            form.remove("pis");
×
790
            form.add(list);
×
791
            target.add(form);
×
792
            target.appendJavaScript("updateElements();");
×
793
        }
794
    }
×
795

796
    private TemplateContext createPubinfoContext(String piTemplateId) {
797
        TemplateContext c;
798
        if (pubInfoContextMap.containsKey(piTemplateId)) {
×
799
            c = pubInfoContextMap.get(piTemplateId);
×
800
        } else {
801
            c = new TemplateContext(ContextType.PUBINFO, piTemplateId, "pi-statement", targetNamespace);
×
802
            pubInfoContextMap.put(piTemplateId, c);
×
803
            pubInfoContexts.add(c);
×
804
        }
805
        return c;
×
806
    }
807

808
    /**
809
     * Predicate for the nanopublication's assertion creation.
810
     */
811
    public static final IRI WAS_CREATED_AT_PREDICATE = vf.createIRI("http://purl.org/nanopub/x/wasCreatedAt");
×
812

813
    private synchronized Nanopub createNanopub() throws MalformedNanopubException {
814
        assertionContext.getIntroducedIris().clear();
×
815
        NanopubCreator npCreator = new NanopubCreator(targetNamespace);
×
816
        npCreator.setAssertionUri(vf.createIRI(targetNamespace + "assertion"));
×
817
        assertionContext.propagateStatements(npCreator);
×
818
        provenanceContext.propagateStatements(npCreator);
×
819
        for (TemplateContext c : pubInfoContexts) {
×
820
            c.propagateStatements(npCreator);
×
821
        }
×
822
        for (IRI introducedIri : assertionContext.getIntroducedIris()) {
×
823
            npCreator.addPubinfoStatement(NanopubUtils.INTRODUCES, introducedIri);
×
824
        }
×
825
        for (IRI embeddedIri : assertionContext.getEmbeddedIris()) {
×
826
            npCreator.addPubinfoStatement(NanopubUtils.EMBEDS, embeddedIri);
×
827
        }
×
828
        npCreator.addNamespace("this", targetNamespace);
×
829
        npCreator.addNamespace("sub", targetNamespace + "/");
×
830
        npCreator.addTimestampNow();
×
831
        IRI templateUri = assertionContext.getTemplate().getNanopub().getUri();
×
832
        npCreator.addPubinfoStatement(Template.WAS_CREATED_FROM_TEMPLATE_PREDICATE, templateUri);
×
833
        IRI prTemplateUri = provenanceContext.getTemplate().getNanopub().getUri();
×
834
        npCreator.addPubinfoStatement(Template.WAS_CREATED_FROM_PROVENANCE_TEMPLATE_PREDICATE, prTemplateUri);
×
835
        for (TemplateContext c : pubInfoContexts) {
×
836
            IRI piTemplateUri = c.getTemplate().getNanopub().getUri();
×
837
            npCreator.addPubinfoStatement(Template.WAS_CREATED_FROM_PUBINFO_TEMPLATE_PREDICATE, piTemplateUri);
×
838
        }
×
839
        String nanopubLabel = getNanopubLabel(npCreator);
×
840
        if (nanopubLabel != null) {
×
841
            npCreator.addPubinfoStatement(RDFS.LABEL, vf.createLiteral(nanopubLabel));
×
842
        }
843
        for (IRI type : assertionContext.getTemplate().getTargetNanopubTypes()) {
×
844
            npCreator.addPubinfoStatement(NanopubUtils.HAS_NANOPUB_TYPE, type);
×
845
        }
×
846
        IRI userIri = NanodashSession.get().getUserIri();
×
847
        if (User.getName(userIri) != null) {
×
848
            npCreator.addPubinfoStatement(userIri, FOAF.NAME, vf.createLiteral(User.getName(userIri)));
×
849
            npCreator.addNamespace("foaf", FOAF.NAMESPACE);
×
850
        }
851
        String websiteUrl = NanodashPreferences.get().getWebsiteUrl();
×
852
        if (websiteUrl != null) {
×
853
            npCreator.addPubinfoStatement(WAS_CREATED_AT_PREDICATE, vf.createIRI(websiteUrl));
×
854
        }
855
        return npCreator.finalizeNanopub();
×
856
    }
857

858
    private String getNanopubLabel(NanopubCreator npCreator) {
859
        if (assertionContext.getTemplate().getNanopubLabelPattern() == null) return null;
×
860

861
        Map<IRI, String> labelMap = new HashMap<>();
×
862
        for (Statement st : npCreator.getCurrentPubinfoStatements()) {
×
863
            if (st.getPredicate().equals(RDFS.LABEL) && st.getObject() instanceof Literal objL) {
×
864
                labelMap.put((IRI) st.getSubject(), objL.stringValue());
×
865
            }
866
        }
×
867

868
        String nanopubLabel = assertionContext.getTemplate().getNanopubLabelPattern();
×
869
        while (nanopubLabel.matches(".*\\$\\{[_a-zA-Z0-9-]+\\}.*")) {
×
870
            String placeholderPostfix = nanopubLabel.replaceFirst("^.*\\$\\{([_a-zA-Z0-9-]+)\\}.*$", "$1");
×
871
            IRI placeholderIriHash = vf.createIRI(assertionContext.getTemplateId() + "#" + placeholderPostfix);
×
872
            IRI placeholderIriSlash = vf.createIRI(assertionContext.getTemplateId() + "/" + placeholderPostfix);
×
873
            IRI placeholderIri = null;
×
874
            String placeholderValue = "";
×
875
            if (assertionContext.getComponentModels().get(placeholderIriSlash) != null) {
×
876
                placeholderIri = placeholderIriSlash;
×
877
            } else {
878
                placeholderIri = placeholderIriHash;
×
879
            }
880
            IModel<String> m = assertionContext.getComponentModels().get(placeholderIri);
×
881
            if (m != null) placeholderValue = m.orElse("").getObject();
×
882
            if (placeholderValue == null) placeholderValue = "";
×
883
            String placeholderLabel = placeholderValue;
×
884
            if (assertionContext.getTemplate().isUriPlaceholder(placeholderIri)) {
×
885
                try {
886
                    // TODO Fix this. It doesn't work for placeholders with auto-encode placeholders, etc.
887
                    //      Not sure we need labels for these, but this code should be improved anyway.
888
                    String prefix = assertionContext.getTemplate().getPrefix(placeholderIri);
×
889
                    if (prefix != null) placeholderValue = prefix + placeholderValue;
×
890
                    IRI placeholderValueIri = vf.createIRI(placeholderValue);
×
891
                    String l = assertionContext.getTemplate().getLabel(placeholderValueIri);
×
892
                    if (labelMap.containsKey(placeholderValueIri)) {
×
893
                        l = labelMap.get(placeholderValueIri);
×
894
                    }
895
                    if (l == null) l = GuidedChoiceItem.getLabel(placeholderValue);
×
896
                    if (assertionContext.getTemplate().isAgentPlaceholder(placeholderIri) && !placeholderValue.isEmpty()) {
×
897
                        l = User.getName(vf.createIRI(placeholderValue));
×
898
                    }
899
                    if (l != null && !l.isEmpty()) {
×
900
                        placeholderLabel = l.replaceFirst(" - .*$", "");
×
901
                    } else {
902
                        placeholderLabel = Utils.getShortNameFromURI(placeholderValueIri);
×
903
                    }
904
                } catch (Exception ex) {
×
905
                    ex.printStackTrace();
×
906
                }
×
907
            }
908
            placeholderLabel = placeholderLabel.replaceAll("\\s+", " ");
×
909
            if (placeholderLabel.length() > 100) placeholderLabel = placeholderLabel.substring(0, 97) + "...";
×
910
            nanopubLabel = StringUtils.replace(nanopubLabel, "${" + placeholderPostfix + "}", placeholderLabel);
×
911
        }
×
912
        return nanopubLabel;
×
913
    }
914

915
    private NanodashPage getConfirmPage(Nanopub signedNp, PageParameters pageParams) {
916
        try {
917
            return (NanodashPage) confirmPageClass.getConstructor(Nanopub.class, PageParameters.class).newInstance(signedNp, pageParams);
×
918
        } catch (InstantiationException | IllegalAccessException | IllegalArgumentException |
×
919
                 InvocationTargetException | NoSuchMethodException | SecurityException ex) {
920
            ex.printStackTrace();
×
921
        }
922
        return null;
×
923
    }
924

925
    /**
926
     * Returns a hint whether the form is stateless or not.
927
     *
928
     * @return false if the form is stateful, true if it is stateless.
929
     */
930
    // This is supposed to solve the problem that sometimes (but only sometimes) form content is reset
931
    // if the user browses other pages in parallel:
932
    protected boolean getStatelessHint() {
933
        return false;
×
934
    }
935

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