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

knowledgepixels / nanodash / 18653097879

20 Oct 2025 01:11PM UTC coverage: 13.053% (-0.5%) from 13.583%
18653097879

push

github

web-flow
Merge pull request #265 from knowledgepixels/252-datetime-picker-datetime-literal-placeholders

Add date pickers for date/datetime literal placeholders

450 of 4316 branches covered (10.43%)

Branch coverage included in aggregate %.

1157 of 7995 relevant lines covered (14.47%)

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

3
import com.knowledgepixels.nanodash.Utils;
4
import com.knowledgepixels.nanodash.template.Template;
5
import com.knowledgepixels.nanodash.template.TemplateContext;
6
import com.knowledgepixels.nanodash.template.UnificationException;
7
import org.apache.wicket.AttributeModifier;
8
import org.apache.wicket.Component;
9
import org.apache.wicket.ajax.AjaxRequestTarget;
10
import org.apache.wicket.ajax.form.OnChangeAjaxBehavior;
11
import org.apache.wicket.markup.html.basic.Label;
12
import org.apache.wicket.markup.html.form.AbstractTextComponent;
13
import org.apache.wicket.markup.html.form.TextField;
14
import org.apache.wicket.markup.html.panel.Panel;
15
import org.apache.wicket.model.IModel;
16
import org.apache.wicket.model.Model;
17
import org.apache.wicket.validation.IValidator;
18
import org.apache.wicket.validation.ValidationError;
19
import org.eclipse.rdf4j.model.IRI;
20
import org.eclipse.rdf4j.model.Literal;
21
import org.eclipse.rdf4j.model.Value;
22
import org.eclipse.rdf4j.model.util.Literals;
23
import org.eclipse.rdf4j.model.vocabulary.XSD;
24
import org.slf4j.Logger;
25
import org.slf4j.LoggerFactory;
26

27
/**
28
 * A component that represents a text field for entering literal values.
29
 */
30
public class LiteralTextfieldItem extends Panel implements ContextComponent {
31

32
    private TemplateContext context;
33
    private AbstractTextComponent<String> textfield;
34
    private Label languageComp, datatypeComp;
35
    private IModel<String> languageModel, datatypeModel;
36
    private final String regex;
37
    private final IRI iri;
38
    private final static Logger logger = LoggerFactory.getLogger(LiteralTextfieldItem.class);
×
39

40
    /**
41
     * Constructs a LiteralTextfieldItem with the specified ID, IRI, optional flag, and template context.
42
     *
43
     * @param id       the component ID
44
     * @param iri      the IRI associated with this text field
45
     * @param optional whether this field is optional
46
     * @param context  the template context containing models and parameters
47
     */
48
    public LiteralTextfieldItem(String id, final IRI iri, boolean optional, TemplateContext context) {
49
        super(id);
×
50
        this.context = context;
×
51
        final Template template = context.getTemplate();
×
52
        this.iri = iri;
×
53
        regex = template.getRegex(iri);
×
54
        IModel<String> model = (IModel<String>) context.getComponentModels().get(iri);
×
55
        if (model == null) {
×
56
            model = Model.of("");
×
57
            context.getComponentModels().put(iri, model);
×
58
        }
59
        String postfix = Utils.getUriPostfix(iri);
×
60
        if (context.hasParam(postfix)) {
×
61
            model.setObject(context.getParam(postfix));
×
62
        }
63
        AbstractTextComponent<String> tc = initTextComponent(model);
×
64
        if (!optional) tc.setRequired(true);
×
65
        if (context.getTemplate().getLabel(iri) != null) {
×
66
            tc.add(new AttributeModifier("placeholder", context.getTemplate().getLabel(iri)));
×
67
        }
68
        tc.add((IValidator<String>) s -> {
×
69
            if (regex != null) {
×
70
                if (!s.getValue().matches(regex)) {
×
71
                    s.error(new ValidationError("Value '" + s.getValue() + "' doesn't match the pattern '" + regex + "'"));
×
72
                }
73
            }
74
        });
×
75

76
        tc.add(new OnChangeAjaxBehavior() {
×
77
            @Override
78
            protected void onUpdate(AjaxRequestTarget target) {
79
                for (Component c : context.getComponents()) {
×
80
                    if (c == tc) continue;
×
81
                    if (c.getDefaultModel() == tc.getModel()) {
×
82
                        c.modelChanged();
×
83
                        target.add(c);
×
84
                    }
85
                }
×
86
            }
×
87
        });
88
        context.getComponentModels().put(iri, tc.getModel());
×
89
        context.getComponents().add(tc);
×
90
        tc.add(new ValueItem.KeepValueAfterRefreshBehavior());
×
91
        tc.add(new InvalidityHighlighting());
×
92
        add(tc);
×
93

94
        languageModel = Model.of("");
×
95
        languageComp = new Label("language", languageModel);
×
96
        datatypeModel = Model.of("");
×
97
        datatypeComp = new Label("datatype", datatypeModel);
×
98
        if (template.getLanguageTag(iri) != null) {
×
99
            languageModel.setObject("(" + template.getLanguageTag(iri) + ")");
×
100
            datatypeComp.setVisible(false);
×
101
        } else if (template.getDatatype(iri) != null && !template.getDatatype(iri).equals(XSD.STRING)) {
×
102
            datatypeModel.setObject("(" + template.getDatatype(iri).stringValue().replace(XSD.NAMESPACE, "xsd:") + ")");
×
103
            languageComp.setVisible(false);
×
104
        } else {
105
            datatypeComp.setVisible(false);
×
106
            languageComp.setVisible(false);
×
107
        }
108
        add(languageComp);
×
109
        add(datatypeComp);
×
110
    }
×
111

112
    /**
113
     * <p>initTextComponent.</p>
114
     *
115
     * @param model a {@link org.apache.wicket.model.IModel} object
116
     * @return a {@link org.apache.wicket.markup.html.form.AbstractTextComponent} object
117
     */
118
    protected AbstractTextComponent<String> initTextComponent(IModel<String> model) {
119
        textfield = new TextField<>("textfield", model);
×
120
        return textfield;
×
121
    }
122

123
    /**
124
     * <p>getTextComponent.</p>
125
     *
126
     * @return a {@link org.apache.wicket.markup.html.form.AbstractTextComponent} object
127
     */
128
    protected AbstractTextComponent<String> getTextComponent() {
129
        return textfield;
×
130
    }
131

132
    /**
133
     * {@inheritDoc}
134
     */
135
    @Override
136
    public void removeFromContext() {
137
        context.getComponents().remove(getTextComponent());
×
138
    }
×
139

140
    /**
141
     * {@inheritDoc}
142
     */
143
    @Override
144
    public boolean isUnifiableWith(Value v) {
145
        if (v == null) return true;
×
146
        if (v instanceof Literal vL) {
×
147
            if (regex != null && !vL.stringValue().matches(regex)) {
×
148
                return false;
×
149
            }
150
            if (getTextComponent().getModelObject().isEmpty()) {
×
151
                return true;
×
152
            }
153
            String languagetag = context.getTemplate().getLanguageTag(iri);
×
154
            IRI datatype = context.getTemplate().getDatatype(iri);
×
155
            if (languagetag != null) {
×
156
                if (!vL.getLanguage().isPresent() || !Literals.normalizeLanguageTag(vL.getLanguage().get()).equals(languagetag)) {
×
157
                    return false;
×
158
                }
159
            } else if (datatype != null) {
×
160
                if (!vL.getDatatype().equals(datatype)) {
×
161
                    return false;
×
162
                }
163
            }
164
            return vL.stringValue().equals(getTextComponent().getModelObject());
×
165
        }
166
        return false;
×
167
    }
168

169
    /**
170
     * {@inheritDoc}
171
     */
172
    @Override
173
    public void unifyWith(Value v) throws UnificationException {
174
        if (v == null) return;
×
175
        if (!isUnifiableWith(v)) throw new UnificationException(v.stringValue());
×
176
        Literal vL = (Literal) v;
×
177
        getTextComponent().setModelObject(vL.stringValue());
×
178
        if (context.getTemplate().getLanguageTag(iri) == null && vL.getLanguage().isPresent()) {
×
179
            languageModel.setObject("(" + vL.getLanguage().get().toLowerCase() + ")");
×
180
            languageComp.setVisible(true);
×
181
        } else if (context.getTemplate().getDatatype(iri) == null && !vL.getDatatype().equals(XSD.STRING)) {
×
182
            datatypeModel.setObject("(" + vL.getDatatype().stringValue().replace(XSD.NAMESPACE, "xsd:") + ")");
×
183
            datatypeComp.setVisible(true);
×
184
        }
185

186
        getTextComponent().setModelObject(v.stringValue());
×
187
    }
×
188

189
    /**
190
     * {@inheritDoc}
191
     */
192
    @Override
193
    public void fillFinished() {
194
    }
×
195

196
    /**
197
     * {@inheritDoc}
198
     */
199
    @Override
200
    public void finalizeValues() {
201
        Value defaultValue = context.getTemplate().getDefault(iri);
×
202
        if (isUnifiableWith(defaultValue)) {
×
203
            try {
204
                unifyWith(defaultValue);
×
205
            } catch (UnificationException ex) {
×
206
                logger.error("Could not unify with default value.", ex);
×
207
            }
×
208
        }
209
    }
×
210

211
    /**
212
     * {@inheritDoc}
213
     */
214
    @Override
215
    public String toString() {
216
        return "[Literal textfield item]";
×
217
    }
218

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