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

knowledgepixels / nanodash / 30350726166

28 Jul 2026 10:25AM UTC coverage: 33.442% (+3.1%) from 30.298%
30350726166

push

github

web-flow
Merge pull request #567 from knowledgepixels/feat/reject-literals-in-subject-predicate

Report and block templates with literals in subject/predicate position

2337 of 7695 branches covered (30.37%)

Branch coverage included in aggregate %.

4532 of 12845 relevant lines covered (35.28%)

5.43 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

74.42
src/main/java/com/knowledgepixels/nanodash/component/TemplateFormPreview.java
1
package com.knowledgepixels.nanodash.component;
2

3
import com.knowledgepixels.nanodash.NanodashSession;
4
import com.knowledgepixels.nanodash.domain.User;
5
import com.knowledgepixels.nanodash.template.ContextType;
6
import com.knowledgepixels.nanodash.template.Template;
7
import com.knowledgepixels.nanodash.template.TemplateContext;
8
import com.knowledgepixels.nanodash.template.TemplateData;
9
import org.apache.wicket.markup.html.WebMarkupContainer;
10
import org.apache.wicket.markup.html.basic.Label;
11
import org.apache.wicket.markup.html.form.Form;
12
import org.apache.wicket.markup.html.list.ListItem;
13
import org.apache.wicket.markup.html.list.ListView;
14
import org.apache.wicket.markup.html.panel.Panel;
15
import org.eclipse.rdf4j.model.IRI;
16
import org.nanopub.Nanopub;
17

18
import java.util.ArrayList;
19
import java.util.List;
20

21
/**
22
 * A preview panel that shows what the template form will look like when used,
23
 * without the consent checkbox and publish/preview buttons.
24
 */
25
public class TemplateFormPreview extends Panel {
26

27
    /**
28
     * Creates a form preview for a template nanopub that may not yet be published.
29
     *
30
     * @param id              the Wicket component ID
31
     * @param templateNanopub the nanopub that defines the assertion template to preview
32
     */
33
    public TemplateFormPreview(String id, Nanopub templateNanopub) {
34
        super(id);
9✔
35

36
        TemplateData td = TemplateData.get();
6✔
37

38
        // Register the template from the nanopub so it can be looked up by TemplateContext
39
        Template template = td.registerTemplate(templateNanopub);
12✔
40
        String templateId = template.getId();
9✔
41

42
        String targetNamespace = template.getTargetNamespace();
9✔
43
        if (targetNamespace == null) {
6!
44
            targetNamespace = Template.DEFAULT_TARGET_NAMESPACE;
6✔
45
        }
46
        targetNamespace = targetNamespace + "~~~ARTIFACTCODE~~~/";
9✔
47

48
        // Assertion context
49
        TemplateContext assertionContext = new TemplateContext(ContextType.ASSERTION, templateId, "statement", targetNamespace);
24✔
50
        assertionContext.initStatements();
6✔
51
        assertionContext.finalizeStatements();
6✔
52

53
        // Provenance context
54
        String prTemplateId;
55
        if (template.getDefaultProvenance() != null) {
9!
56
            prTemplateId = template.getDefaultProvenance().stringValue();
×
57
        } else {
58
            prTemplateId = PublishForm.DEFAULT_PROV_TEMPLATE;
6✔
59
        }
60
        TemplateContext provenanceContext = new TemplateContext(ContextType.PROVENANCE, prTemplateId, "pr-statement", targetNamespace);
24✔
61
        provenanceContext.initStatements();
6✔
62
        provenanceContext.finalizeStatements();
6✔
63

64
        // Pubinfo contexts
65
        List<TemplateContext> pubInfoContexts = new ArrayList<>();
12✔
66
        pubInfoContexts.add(new TemplateContext(ContextType.PUBINFO, PublishForm.CREATOR_PUB_INFO_TEMPLATE, "pi-statement", targetNamespace));
30✔
67
        TemplateContext licenseContext = new TemplateContext(ContextType.PUBINFO, PublishForm.LICENSE_PUB_INFO_TEMPLATE, "pi-statement", targetNamespace);
24✔
68
        IRI defaultLicense = User.getDefaultLicense(NanodashSession.get().getUserIri());
12✔
69
        if (defaultLicense != null) {
6!
70
            licenseContext.setParam("license", defaultLicense.stringValue());
×
71
        }
72
        pubInfoContexts.add(licenseContext);
12✔
73
        for (IRI r : template.getRequiredPubInfoElements()) {
21!
74
            String rId = r.stringValue();
×
75
            boolean alreadyAdded = false;
×
76
            for (TemplateContext c : pubInfoContexts) {
×
77
                if (c.getTemplate().hasId(rId)) {
×
78
                    alreadyAdded = true;
×
79
                    break;
×
80
                }
81
            }
×
82
            if (!alreadyAdded) {
×
83
                pubInfoContexts.add(new TemplateContext(ContextType.PUBINFO, rId, "pi-statement", targetNamespace));
×
84
            }
85
        }
×
86
        for (TemplateContext c : pubInfoContexts) {
30✔
87
            c.initStatements();
6✔
88
            c.finalizeStatements();
6✔
89
        }
3✔
90

91
        // Statements that cannot produce valid RDF (e.g. a literal in subject position) are
92
        // listed above the form, which still renders so the problem can be located in it.
93
        List<String> statementErrors = template.getStatementErrors();
9✔
94
        WebMarkupContainer errorSection = new WebMarkupContainer("errors");
15✔
95
        errorSection.add(new ListView<String>("error", statementErrors) {
66✔
96
            protected void populateItem(ListItem<String> item) {
97
                item.add(new Label("errormessage", item.getModelObject()));
45✔
98
            }
3✔
99
        });
100
        errorSection.setVisible(!statementErrors.isEmpty());
27✔
101
        add(errorSection);
27✔
102

103
        // Build the form (needed for Wicket form components to render, but no submit action)
104
        Form<?> form = new Form<Void>("form");
15✔
105

106
        // Assertion section
107
        form.add(PublishForm.newSourceMenu("templatelink", templateId));
33✔
108
        form.add(new Label("templatename", template.getLabel()));
42✔
109
        form.add(new Label("templatedesc", template.getDescription()).setEscapeModelStrings(false));
48✔
110

111
        form.add(new ListView<StatementItem>("statements", assertionContext.getStatementItems()) {
69✔
112
            protected void populateItem(ListItem<StatementItem> item) {
113
                item.add(item.getModelObject());
33✔
114
            }
3✔
115
        });
116

117
        // Provenance section
118
        form.add(new Label("prtemplatename", provenanceContext.getTemplate().getLabel()));
45✔
119
        form.add(PublishForm.newSourceMenu("prtemplatelink", provenanceContext.getTemplate().getId()));
39✔
120

121
        form.add(new ListView<StatementItem>("pr-statements", provenanceContext.getStatementItems()) {
69✔
122
            protected void populateItem(ListItem<StatementItem> item) {
123
                item.add(item.getModelObject());
33✔
124
            }
3✔
125
        });
126

127
        // Pubinfo section
128
        form.add(new ListView<TemplateContext>("pis", pubInfoContexts) {
66✔
129
            protected void populateItem(ListItem<TemplateContext> item) {
130
                TemplateContext pic = item.getModelObject();
12✔
131
                item.add(new Label("pitemplatename", pic.getTemplate().getLabel()));
45✔
132
                item.add(PublishForm.newSourceMenu("pitemplatelink", pic.getTemplate().getId()));
39✔
133
                item.add(new ListView<StatementItem>("pi-statements", pic.getStatementItems()) {
69✔
134
                    protected void populateItem(ListItem<StatementItem> item) {
135
                        item.add(item.getModelObject());
33✔
136
                    }
3✔
137
                });
138
            }
3✔
139
        });
140

141
        add(form);
27✔
142
    }
3✔
143

144
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc