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

knowledgepixels / nanodash / 26093859530

19 May 2026 11:20AM UTC coverage: 20.748% (-0.03%) from 20.776%
26093859530

push

github

tkuhn
fix: surface root nanopub placeholder as "this nanopublication" in supersede

When superseding with a newer template that adds a RootNanopubPlaceholder
slot the prior nanopub didn't have, the form left the field blank even
though TemplateContext.processValue already resolves an empty model to
the new nanopub's URI. Render the label, tooltip description, and URI
sentinel so the form matches the IriItem NANOPUB_PLACEHOLDER rendering.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

1033 of 6298 branches covered (16.4%)

Branch coverage included in aggregate %.

2649 of 11448 relevant lines covered (23.14%)

3.31 hits per line

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

0.0
src/main/java/com/knowledgepixels/nanodash/component/ReadonlyItem.java
1
package com.knowledgepixels.nanodash.component;
2

3
import com.knowledgepixels.nanodash.LocalUri;
4
import com.knowledgepixels.nanodash.RestrictedChoice;
5
import com.knowledgepixels.nanodash.domain.User;
6
import com.knowledgepixels.nanodash.Utils;
7
import com.knowledgepixels.nanodash.component.StatementItem.RepetitionGroup;
8
import com.knowledgepixels.nanodash.domain.IndividualAgent;
9
import com.knowledgepixels.nanodash.domain.MaintainedResource;
10
import com.knowledgepixels.nanodash.domain.Space;
11
import com.knowledgepixels.nanodash.page.ExplorePage;
12
import com.knowledgepixels.nanodash.repository.MaintainedResourceRepository;
13
import com.knowledgepixels.nanodash.repository.SpaceRepository;
14
import com.knowledgepixels.nanodash.template.ContextType;
15
import com.knowledgepixels.nanodash.template.Template;
16
import com.knowledgepixels.nanodash.template.UnificationException;
17
import net.trustyuri.TrustyUriUtils;
18
import org.apache.commons.codec.Charsets;
19
import org.apache.wicket.behavior.AttributeAppender;
20
import org.apache.wicket.markup.html.basic.Label;
21
import org.apache.wicket.markup.html.link.ExternalLink;
22
import org.apache.wicket.model.IModel;
23
import org.apache.wicket.model.Model;
24
import org.apache.wicket.validation.IValidatable;
25
import org.apache.wicket.validation.IValidator;
26
import org.apache.wicket.validation.Validatable;
27
import org.apache.wicket.validation.ValidationError;
28
import org.eclipse.rdf4j.common.net.ParsedIRI;
29
import org.eclipse.rdf4j.model.IRI;
30
import org.eclipse.rdf4j.model.Literal;
31
import org.eclipse.rdf4j.model.Value;
32
import org.eclipse.rdf4j.model.ValueFactory;
33
import org.eclipse.rdf4j.model.impl.SimpleValueFactory;
34
import org.eclipse.rdf4j.model.util.Literals;
35
import org.eclipse.rdf4j.model.vocabulary.XSD;
36
import org.nanopub.Nanopub;
37
import org.nanopub.NanopubUtils;
38
import org.nanopub.SimpleCreatorPattern;
39
import org.nanopub.vocabulary.NTEMPLATE;
40
import org.slf4j.Logger;
41
import org.slf4j.LoggerFactory;
42

43
import java.net.URISyntaxException;
44
import java.net.URLEncoder;
45
import java.util.HashMap;
46
import java.util.Map;
47

48
/**
49
 * ReadonlyItem is a component that displays a read-only item in the form.
50
 */
51
public class ReadonlyItem extends AbstractContextComponent {
52

53
    private static final int LONG_LITERAL_LENGTH = 100;
54
    private static final Logger logger = LoggerFactory.getLogger(ReadonlyItem.class);
×
55
    private static final ValueFactory vf = SimpleValueFactory.getInstance();
×
56

57
    private IModel<String> model;
58
    private String prefix;
59
    private ExternalLink linkComp;
60
    private Label extraComp, languageComp, datatypeComp;
61
    private IModel<String> extraModel, languageModel, datatypeModel;
62
    private IRI iri;
63
    private RestrictedChoice restrictedChoice;
64
    private Label showMoreLabelLiteral, showMoreLabelHTML;
65
    private final Template template;
66

67
    /**
68
     * Constructor for ReadonlyItem.
69
     *
70
     * @param id              the component id
71
     * @param parentId        the parent id (e.g., "subj", "obj")
72
     * @param iriP            the IRI of the item
73
     * @param statementPartId the statement part ID
74
     * @param rg              the repetition group
75
     */
76
    public ReadonlyItem(String id, String parentId, final IRI iriP, IRI statementPartId, final RepetitionGroup rg) {
77
        super(id, rg.getContext());
×
78
        this.iri = iriP;
×
79
        template = context.getTemplate();
×
80
        model = (IModel<String>) context.getComponentModels().get(iri);
×
81
        boolean modelIsNew = false;
×
82
        if (model == null) {
×
83
            model = Model.of("");
×
84
            context.getComponentModels().put(iri, model);
×
85
            modelIsNew = true;
×
86
        }
87
        String postfix = Utils.getUriPostfix(iri);
×
88
        if (modelIsNew && context.hasParam(postfix)) {
×
89
            model.setObject(context.getParam(postfix));
×
90
        }
91
        if (model.getObject().isEmpty() && template.isRootNanopubPlaceholder(iri) && context.getReferenceNanopub() == null) {
×
92
            model.setObject(LocalUri.of("nanopub").stringValue());
×
93
        }
94

95
        final Map<String, String> foafNameMap;
96
        if (context.getExistingNanopub() == null) {
×
97
            foafNameMap = new HashMap<>();
×
98
        } else {
99
            foafNameMap = Utils.getFoafNameMap(context.getExistingNanopub());
×
100
        }
101

102
        prefix = template.getPrefix(iri);
×
103
        if (prefix == null) prefix = "";
×
104
        if (template.isRestrictedChoicePlaceholder(iri)) {
×
105
            restrictedChoice = new RestrictedChoice(iri, context);
×
106
        }
107
        add(new Label("prefix", new Model<String>() {
×
108

109
            @Override
110
            public String getObject() {
111
                String prefixLabel = template.getPrefixLabel(iri);
×
112
                String v = getFullValue();
×
113
                if (prefixLabel == null || IndividualAgent.isUser(v) || foafNameMap.containsKey(v)) {
×
114
                    return "";
×
115
                } else if (prefixLabel.matches("https?://.*")) {
×
116
                    // Hide prefix label that leaks through as a raw URL.
117
                    return "";
×
118
                } else {
119
                    if (!prefixLabel.isEmpty() && parentId.equals("subj")) {
×
120
                        // Capitalize first letter of label if at subject position:
121
                        prefixLabel = prefixLabel.substring(0, 1).toUpperCase() + prefixLabel.substring(1);
×
122
                    }
123
                    return prefixLabel;
×
124
                }
125
            }
126

127
        }));
128

129
        linkComp = new ExternalLink("link", new Model<String>() {
×
130

131
            @Override
132
            public String getObject() {
133
                String obj = getFullValue();
×
134
                if (obj == null) return "";
×
135
                if (obj.equals(LocalUri.of("nanopub").stringValue())) {
×
136
                    if (context.getExistingNanopub() != null) {
×
137
                        obj = context.getExistingNanopub().getUri().stringValue();
×
138
                        return ExplorePage.MOUNT_PATH + "?id=" + URLEncoder.encode(obj, Charsets.UTF_8);
×
139
                    } else {
140
                        return "";
×
141
                    }
142
                } else if (obj.equals(LocalUri.of("assertion").stringValue())) {
×
143
                    if (context.getExistingNanopub() != null) {
×
144
                        obj = context.getExistingNanopub().getAssertionUri().stringValue();
×
145
                        return ExplorePage.MOUNT_PATH + "?id=" + URLEncoder.encode(obj, Charsets.UTF_8);
×
146
                    } else {
147
                        return "";
×
148
                    }
149
                } else if (obj.matches("https?://.+")) {
×
150
                    return NanodashLink.getPageUrl(obj);
×
151
                } else {
152
                    return "";
×
153
                }
154
            }
155

156
        }, new Model<String>() {
×
157

158
            @Override
159
            public String getObject() {
160
                String obj = getFullValue();
×
161
                if ((obj == null || obj.isEmpty()) && template.isRootNanopubPlaceholder(iri)) {
×
162
                    // No prior value migrated (e.g. supersede with a newer template that added this slot).
163
                    // The empty model already resolves to the new nanopub in TemplateContext.processValue,
164
                    // so surface that to the user in the form.
165
                    return "this nanopublication";
×
166
                }
167
                if (obj != null && obj.equals(LocalUri.of("nanopub").stringValue())) {
×
168
                    return "this nanopublication";
×
169
                }
170
                if (obj != null && obj.equals(LocalUri.of("assertion").stringValue())) {
×
171
                    return context.getType() == ContextType.ASSERTION ? "this assertion" : "the assertion above";
×
172
                }
173
                if (obj != null && obj.matches("https?://.+")) {
×
174
                    IRI objIri = vf.createIRI(obj);
×
175
                    if (iri.equals(NTEMPLATE.CREATOR_PLACEHOLDER)) {
×
176
                        // TODO We might want to introduce a "(you)" flag here at some point
177
                        return User.getShortDisplayName(objIri);
×
178
                    } else if (isAssertionValue(objIri)) {
×
179
                        if (context.getType() == ContextType.ASSERTION) {
×
180
                            return "this assertion";
×
181
                        } else {
182
                            return "the assertion above";
×
183
                        }
184
                    } else if (isNanopubValue(objIri)) {
×
185
                        return "this nanopublication";
×
186
                    } else if (IndividualAgent.isUser(obj)) {
×
187
                        return User.getShortDisplayName(objIri);
×
188
                    } else if (foafNameMap.containsKey(obj)) {
×
189
                        return foafNameMap.get(obj);
×
190
                    }
191
                    Space space = SpaceRepository.get().findById(obj);
×
192
                    if (space != null) return space.getLabel();
×
193
                    space = SpaceRepository.get().findByAltId(obj);
×
194
                    if (space != null) return space.getLabel();
×
195
                    MaintainedResource mr = MaintainedResourceRepository.get().findById(obj);
×
196
                    if (mr != null) return mr.getLabel();
×
197
                    return getLabelString(objIri);
×
198
                }
199
                return obj;
×
200
            }
201

202
        });
203
        if (template.isIntroducedResource(iri) || template.isEmbeddedResource(iri)) {
×
204
            linkComp.add(AttributeAppender.append("class", "introduced"));
×
205
        }
206
        add(linkComp);
×
207
        add(new Label("description", new Model<String>() {
×
208

209
            @Override
210
            public String getObject() {
211
                String obj = getFullValue();
×
212
                if ((obj == null || obj.isEmpty()) && template.isRootNanopubPlaceholder(iri)) {
×
213
                    return "This is the identifier for this whole nanopublication.";
×
214
                }
215
                if (obj != null && obj.matches("https?://.+")) {
×
216
                    IRI objIri = vf.createIRI(obj);
×
217
                    if (isAssertionValue(objIri)) {
×
218
                        return "This is the identifier for the assertion of this nanopublication.";
×
219
                    } else if (isNanopubValue(objIri)) {
×
220
                        return "This is the identifier for this whole nanopublication.";
×
221
                    } else if (context.isReadOnly() && obj.startsWith(context.getExistingNanopub().getUri().stringValue())) {
×
222
                        return "This is a local identifier minted within the nanopublication.";
×
223
                    }
224
                    String labelString = getLabelString(objIri);
×
225
                    String description = "";
×
226
                    if (labelString.contains(" - ")) description = labelString.replaceFirst("^.* - ", "");
×
227
                    return description;
×
228
                } else if (obj != null && obj.startsWith("\"")) {
×
229
                    return "(this is a literal)";
×
230
                }
231
                return "";
×
232
            }
233

234
        }));
235
        Model<String> uriModel = new Model<String>() {
×
236

237
            @Override
238
            public String getObject() {
239
                String obj = getFullValue();
×
240
                if ((obj == null || obj.isEmpty()) && template.isRootNanopubPlaceholder(iri)) {
×
241
                    return LocalUri.of("nanopub").stringValue();
×
242
                }
243
                if (obj != null && obj.startsWith("\"")) return "";
×
244
                if (isAssertionValue(obj)) {
×
245
                    return getAssertionValue();
×
246
                } else if (isNanopubValue(obj)) {
×
247
                    return getNanopubValue();
×
248
                }
249
                return obj;
×
250
            }
251

252
        };
253
        add(Utils.getUriLink("uri", uriModel));
×
254
        extraModel = Model.of("");
×
255
        extraComp = new Label("extra", extraModel);
×
256
        extraComp.setVisible(false);
×
257
        add(extraComp);
×
258
        languageModel = Model.of("");
×
259
        languageComp = new Label("language", languageModel);
×
260
        languageComp.setVisible(false);
×
261
        add(languageComp);
×
262
        datatypeModel = Model.of("");
×
263
        datatypeComp = new Label("datatype", datatypeModel);
×
264
        datatypeComp.setVisible(false);
×
265
        add(datatypeComp);
×
266

267
        showMoreLabelLiteral = new Label("show-more-literal", "");
×
268
        add(showMoreLabelLiteral);
×
269
        showMoreLabelLiteral.setVisible(false);
×
270

271
        showMoreLabelHTML = new Label("show-more-html", "");
×
272
        add(showMoreLabelHTML);
×
273
        showMoreLabelHTML.setVisible(false);
×
274
    }
×
275

276
    /**
277
     * {@inheritDoc}
278
     */
279
    @Override
280
    public void fillFinished() {
281
        String obj = getFullValue();
×
282
        if (obj != null) {
×
283
            if (isAssertionValue(obj)) {
×
284
                linkComp.add(new AttributeAppender("class", "this-assertion"));
×
285
            } else if (isNanopubValue(obj)) {
×
286
                linkComp.add(new AttributeAppender("class", "this-nanopub"));
×
287
            } else if (context.getExistingNanopub() != null) {
×
288
                Nanopub np = context.getExistingNanopub();
×
289
                if (NanopubUtils.getIntroducedIriIds(np).contains(obj) || NanopubUtils.getEmbeddedIriIds(np).contains(obj)) {
×
290
                    linkComp.add(AttributeAppender.append("class", "introduced"));
×
291
                }
292
            }
293
        }
294
    }
×
295

296
    /**
297
     * {@inheritDoc}
298
     */
299
    @Override
300
    public void finalizeValues() {
301
    }
×
302

303
    private String getLabelString(IRI iri) {
304
        if (template.getLabel(iri) != null) {
×
305
            return template.getLabel(iri).replaceFirst(" - .*$", "");
×
306
        } else if (context.getLabel(iri) != null) {
×
307
            return context.getLabel(iri).replaceFirst(" - .*$", "");
×
308
        } else {
309
            return Utils.getShortNameFromURI(iri.stringValue());
×
310
        }
311
    }
312

313
    /**
314
     * {@inheritDoc}
315
     */
316
    @Override
317
    public void removeFromContext() {
318
        // Nothing to be done here.
319
    }
×
320

321
    private String getFullValue() {
322
        String s = model.getObject();
×
323
        if (s == null) return null;
×
324
        if (template.isAutoEscapePlaceholder(iri)) {
×
325
            s = Utils.urlEncode(s);
×
326
        }
327
        if (!prefix.isEmpty()) {
×
328
            s = prefix + s;
×
329
        }
330
        return s;
×
331
    }
332

333
    private boolean isNanopubValue(Object obj) {
334
        if (obj == null) return false;
×
335
        if (obj.toString().equals(LocalUri.of("nanopub").stringValue())) return true;
×
336
        // A fillSource match means a *prior* nanopub (supersede/derive), not "this" one — don't label it as such.
337
        if (context.getExistingNanopub() == null) return false;
×
338
        return obj.toString().equals(context.getExistingNanopub().getUri().stringValue());
×
339
    }
340

341
    private String getNanopubValue() {
342
        Nanopub ref = context.getReferenceNanopub();
×
343
        if (ref != null) {
×
344
            return ref.getUri().stringValue();
×
345
        } else {
346
            return LocalUri.of("nanopub").stringValue();
×
347
        }
348
    }
349

350
    private boolean isAssertionValue(Object obj) {
351
        if (obj == null) return false;
×
352
        if (obj.toString().equals(LocalUri.of("assertion").stringValue())) return true;
×
353
        // A fillSource match means a *prior* assertion (supersede/derive), not "this" one.
354
        if (context.getExistingNanopub() == null) return false;
×
355
        return obj.toString().equals(context.getExistingNanopub().getAssertionUri().stringValue());
×
356
    }
357

358
    private String getAssertionValue() {
359
        Nanopub ref = context.getReferenceNanopub();
×
360
        if (ref != null) {
×
361
            return ref.getAssertionUri().stringValue();
×
362
        } else {
363
            return LocalUri.of("assertion").stringValue();
×
364
        }
365
    }
366

367
    /**
368
     * {@inheritDoc}
369
     */
370
    @Override
371
    public boolean isUnifiableWith(Value v) {
372
        if (v == null) return true;
×
373
        if (v instanceof IRI) {
×
374
            String vs = v.stringValue();
×
375
            if (vs.equals(LocalUri.of("nanopub").stringValue())) {
×
376
                vs = getNanopubValue();
×
377
            } else if (vs.equals(LocalUri.of("assertion").stringValue())) {
×
378
                vs = getAssertionValue();
×
379
            }
380
            if (vs.startsWith(prefix)) vs = vs.substring(prefix.length());
×
381
//                        if (Utils.isLocalURI(vs)) vs = vs.replaceFirst("^" + LocalUri.PREFIX, "");
382
            if (template.isAutoEscapePlaceholder(iri)) {
×
383
                vs = Utils.urlDecode(vs);
×
384
            }
385
            Validatable<String> validatable = new Validatable<>(vs);
×
386
//                        if (template.isLocalResource(iri) && !Utils.isUriPostfix(vs)) {
387
//                                vs = Utils.getUriPostfix(vs);
388
//                        }
389
            new Validator().validate(validatable);
×
390
            if (!validatable.isValid()) {
×
391
                return false;
×
392
            }
393
            if (model.getObject().isEmpty()) {
×
394
                return true;
×
395
            }
396
            return vs.equals(model.getObject());
×
397
        } else if (v instanceof Literal vL) {
×
398
            if (template.getRegex(iri) != null && !v.stringValue().matches(template.getRegex(iri))) {
×
399
                return false;
×
400
            }
401
            String languagetag = template.getLanguageTag(iri);
×
402
            IRI datatype = template.getDatatype(iri);
×
403
            if (languagetag != null) {
×
404
                if (vL.getLanguage().isEmpty() || !Literals.normalizeLanguageTag(vL.getLanguage().get()).equals(languagetag)) {
×
405
                    return false;
×
406
                }
407
            } else if (datatype != null) {
×
408
                if (!vL.getDatatype().equals(datatype)) {
×
409
                    return false;
×
410
                }
411
            }
412
            if (linkComp.getDefaultModelObject() == null || linkComp.getDefaultModelObject().toString().isEmpty()) {
×
413
                return true;
×
414
            }
415
            return linkComp.getDefaultModelObject().equals("\"" + v.stringValue() + "\"");
×
416
        }
417
        return false;
×
418
    }
419

420
    /**
421
     * {@inheritDoc}
422
     */
423
    @Override
424
    public void unifyWith(Value v) throws UnificationException {
425
        if (v == null) return;
×
426
        String vs = v.stringValue();
×
427
        if (!isUnifiableWith(v)) {
×
428
            logger.error("Cannot unify {}", v);
×
429
            throw new UnificationException(vs);
×
430
        }
431
        if (v instanceof IRI) {
×
432
            if (vs.equals(LocalUri.of("nanopub").stringValue())) {
×
433
                vs = getNanopubValue();
×
434
            } else if (vs.equals(LocalUri.of("assertion").stringValue())) {
×
435
                vs = getAssertionValue();
×
436
            }
437
            if (!prefix.isEmpty() && vs.startsWith(prefix)) {
×
438
                vs = vs.substring(prefix.length());
×
439
                // With read-only items, we don't need preliminary local identifiers:
440
//                        } else if (Utils.isLocalURI(vs)) {
441
//                                vs = vs.replaceFirst("^" + LocalUri.PREFIX, "");
442
//                        } else if (template.isLocalResource(iri) && !Utils.isUriPostfix(vs)) {
443
//                                vs = Utils.getUriPostfix(vs);
444
            }
445
            if (template.isAutoEscapePlaceholder(iri)) {
×
446
                vs = Utils.urlDecode(vs);
×
447
            }
448
            model.setObject(vs);
×
449
        } else if (v instanceof Literal vL) {
×
450
            if (vs.length() >= LONG_LITERAL_LENGTH) {
×
451
                linkComp.add(AttributeAppender.append("class", "long-literal collapsed"));
×
452
                showMoreLabelLiteral.setVisible(true);
×
453
            }
454
            if (vL.getLanguage().isPresent()) {
×
455
                model.setObject("\"" + vs + "\"");
×
456
                languageModel.setObject("(" + Literals.normalizeLanguageTag(vL.getLanguage().get()) + ")");
×
457
                languageComp.setVisible(true);
×
458
            } else if (!vL.getDatatype().equals(XSD.STRING)) {
×
459
                model.setObject("\"" + vs + "\"");
×
460
                datatypeModel.setObject("(" + vL.getDatatype().stringValue().replace(XSD.NAMESPACE, "xsd:") + ")");
×
461
                datatypeComp.setVisible(true);
×
462
            } else {
463
                model.setObject("\"" + vs + "\"");
×
464
            }
465
            if (Utils.looksLikeHtml(vs)) {
×
466
                linkComp.setVisible(false);
×
467
                extraModel.setObject(Utils.sanitizeHtml(vs));
×
468
                extraComp.setEscapeModelStrings(false);
×
469
                extraComp.setVisible(true);
×
470
                showMoreLabelLiteral.setVisible(false);
×
471
                showMoreLabelHTML.setVisible(true);
×
472
            }
473
        }
474
    }
×
475

476
    /**
477
     * Validator class for validating the input.
478
     */
479
    protected class Validator extends InvalidityHighlighting implements IValidator<String> {
480

481
        /**
482
         * Default constructor for Validator.
483
         */
484
        public Validator() {
×
485
        }
×
486

487
        @Override
488
        public void validate(IValidatable<String> s) {
489
            String sv = s.getValue();
×
490
            String p = prefix;
×
491
            if (template.isAutoEscapePlaceholder(iri)) {
×
492
                sv = Utils.urlEncode(sv);
×
493
            }
494
            if (sv.matches("https?://.+")) {
×
495
                p = "";
×
496
            } else if (sv.contains(":")) {
×
497
                s.error(new ValidationError("Colon character is not allowed in postfix"));
×
498
            }
499
            String iriString = p + sv;
×
500
            if (iriString.matches("[^:# ]+")) {
×
501
                p = LocalUri.PREFIX;
×
502
                iriString = p + sv;
×
503
            }
504
            try {
505
                ParsedIRI piri = new ParsedIRI(iriString);
×
506
                if (!piri.isAbsolute()) {
×
507
                    s.error(new ValidationError("IRI not well-formed"));
×
508
                }
509
                if (p.isEmpty() && !Utils.isLocalURI(sv) && !sv.matches("https?://.+")) {
×
510
                    s.error(new ValidationError("Only http(s):// IRIs are allowed here"));
×
511
                }
512
            } catch (URISyntaxException ex) {
×
513
                s.error(new ValidationError("IRI not well-formed"));
×
514
            }
×
515
            String regex = template.getRegex(iri);
×
516
            if (regex != null) {
×
517
                if (!sv.matches(regex)) {
×
518
                    s.error(new ValidationError("Value '" + sv + "' doesn't match the pattern '" + regex + "'"));
×
519
                }
520
            }
521
            if (template.isRestrictedChoicePlaceholder(iri)) {
×
522
                if (!restrictedChoice.getPossibleValues().contains(iriString) && !restrictedChoice.hasPossibleRefValues()) {
×
523
                    // not checking the possible ref values can overgenerate, but normally works
524
                    s.error(new ValidationError("Invalid choice"));
×
525
                }
526
            }
527
            if (template.isExternalUriPlaceholder(iri)) {
×
528
                if (!iriString.matches("https?://.+")) {
×
529
                    s.error(new ValidationError("Not an external IRI"));
×
530
                }
531
            }
532
            if (template.isTrustyUriPlaceholder(iri)) {
×
533
                if (!TrustyUriUtils.isPotentialTrustyUri(iriString)) {
×
534
                    s.error(new ValidationError("Not a trusty URI"));
×
535
                }
536
            }
537
            if (iri.equals(NTEMPLATE.CREATOR_PLACEHOLDER) && context.getExistingNanopub() != null) {
×
538
                boolean found = false;
×
539
                for (IRI creator : SimpleCreatorPattern.getCreators(context.getExistingNanopub())) {
×
540
                    if (creator.stringValue().equals(iriString)) {
×
541
                        found = true;
×
542
                        break;
×
543
                    }
544
                }
×
545
                if (!found) {
×
546
                    s.error(new ValidationError("Not a creator of nanopub"));
×
547
                }
548
            }
549
        }
×
550

551
    }
552

553
    /**
554
     * <p>toString.</p>
555
     *
556
     * @return a {@link java.lang.String} object
557
     */
558
    public String toString() {
559
        return "[read-only IRI item: " + iri + "]";
×
560
    }
561

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