diff options
author | jonmv <venstad@gmail.com> | 2023-10-10 14:11:15 +0200 |
---|---|---|
committer | jonmv <venstad@gmail.com> | 2023-10-10 14:11:15 +0200 |
commit | c4face9aeb327f059dc1613b416713a275d807c9 (patch) | |
tree | faf8284c3286b61801c696869eb76496e7c17e17 | |
parent | d61c151211024dbb5e9a5d71ac921217ae00f34b (diff) |
Validate string, uri and reference fields when set in concrete documents
-rw-r--r-- | documentgen-test/src/test/java/com/yahoo/vespa/config/DocumentGenPluginTest.java | 24 | ||||
-rw-r--r-- | vespa-documentgen-plugin/src/main/java/com/yahoo/vespa/DocumentGenMojo.java | 40 |
2 files changed, 62 insertions, 2 deletions
diff --git a/documentgen-test/src/test/java/com/yahoo/vespa/config/DocumentGenPluginTest.java b/documentgen-test/src/test/java/com/yahoo/vespa/config/DocumentGenPluginTest.java index bd2b057835c..b3e78f1e2a8 100644 --- a/documentgen-test/src/test/java/com/yahoo/vespa/config/DocumentGenPluginTest.java +++ b/documentgen-test/src/test/java/com/yahoo/vespa/config/DocumentGenPluginTest.java @@ -79,6 +79,7 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotSame; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertThrows; import static org.junit.Assert.assertTrue; /** @@ -500,6 +501,29 @@ public class DocumentGenPluginTest { assertEquals(book.getFieldValue("isbn"), new StringFieldValue("ISBN YEP")); } + @Test + public void testSetterValidation() { + Book book = new Book(new DocumentId("id:book:book::0")); + + book.setAuthor("Herman Melville"); + assertEquals("The string field value contains illegal code point 0x16", + assertThrows(IllegalArgumentException.class, + () -> book.setAuthor("He\u0016rman Malville")).getMessage()); + + book.setRef(new DocumentId("id:ns:parent::foo")); + assertEquals("Can't assign document ID 'id:ns:common::bar' (of type 'common') to reference of document type 'parent'", + assertThrows(IllegalArgumentException.class, + () -> book.setRef(new DocumentId("id:ns:common::bar"))).getMessage()); + + book.setStringmap(Map.of("foo", "bar")); + assertEquals("The string field value contains illegal code point 0x16", + assertThrows(IllegalArgumentException.class, + () -> book.setStringmap(Map.of("foo", "bar\u0016"))).getMessage()); + assertEquals("The string field value contains illegal code point 0x16", + assertThrows(IllegalArgumentException.class, + () -> book.setStringmap(Map.of("bar\u0016", "foo"))).getMessage()); + } + public static class BookProcessor extends DocumentProcessor { public Progress process(Processing processing) { diff --git a/vespa-documentgen-plugin/src/main/java/com/yahoo/vespa/DocumentGenMojo.java b/vespa-documentgen-plugin/src/main/java/com/yahoo/vespa/DocumentGenMojo.java index 65aecd09931..92f35fdd4f0 100644 --- a/vespa-documentgen-plugin/src/main/java/com/yahoo/vespa/DocumentGenMojo.java +++ b/vespa-documentgen-plugin/src/main/java/com/yahoo/vespa/DocumentGenMojo.java @@ -851,8 +851,12 @@ public class DocumentGenMojo extends AbstractMojo { for (Field field: fields) { DataType dt = field.getDataType(); out.write( - ind(ind)+"public "+toJavaType(dt)+" "+getter(field.getName())+"() { return "+field.getName()+"; }\n"+ - ind(ind)+"public "+className+" "+setter(field.getName())+"("+toJavaType(dt)+" "+field.getName()+") { this."+field.getName()+"="+field.getName()+"; return this; }\n"); + ind(ind) + "public " + toJavaType(dt) + " " + getter(field.getName()) + "() { return " + field.getName() + "; }\n" + + ind(ind) + "public " + className + " " + setter(field.getName()) + "(" + toJavaType(dt) + " " + field.getName() + ") {\n" + + validateArgument(field.getDataType(), field.getName(), ind + 1) + + ind(ind+1) + "this." + field.getName() + "=" + field.getName() + ";\n" + + ind(ind+1) + "return this;\n" + + ind(ind) + "}\n"); if (spanTrees && dt.equals(DataType.STRING)) { out.write(ind(ind)+"public java.util.Map<java.lang.String,com.yahoo.document.annotation.SpanTree> "+spanTreeGetter(field.getName())+"() { return "+field.getName()+"SpanTrees; }\n" + ind(ind)+"public void "+spanTreeSetter(field.getName())+"(java.util.Map<java.lang.String,com.yahoo.document.annotation.SpanTree> spanTrees) { this."+field.getName()+"SpanTrees=spanTrees; }\n"); @@ -861,6 +865,38 @@ public class DocumentGenMojo extends AbstractMojo { out.write("\n"); } + private static String validateArgument(DataType type, String variable, int ind) { + if (type instanceof MapDataType mdt) { + return validateWrapped(mdt.getKeyType(), variable, variable + ".keySet()", ind) + + validateWrapped(mdt.getValueType(), variable, variable + ".values()", ind); + } + else if (type instanceof CollectionDataType cdt) { + String elements = cdt instanceof WeightedSetDataType ? variable + ".keySet()" : variable; + return validateWrapped(cdt.getNestedType(), variable, elements, ind); + } + else if ( DataType.STRING.equals(type) + || DataType.URI.equals(type) + || type instanceof AnnotationReferenceDataType + || type instanceof NewDocumentReferenceDataType) { + return ind(ind) + "if (" + variable + " != null) {\n" + + ind(ind+1) + toJavaReference(type) + ".createFieldValue(" + variable + ");\n" + + ind(ind) + "}\n"; + } + else { + return ""; + } + } + + private static String validateWrapped(DataType type, String variable, String elements, int ind) { + String wrappedValidation = validateArgument(type, variable + "$", ind + 2); + if (wrappedValidation.isBlank()) return ""; + return ind(ind) + "if (" + variable + " != null) {\n" + + ind(ind+1) + "for (" + toJavaType(type) + " " + variable + "$ : " + elements + ") {\n" + + wrappedValidation + + ind(ind+1) + "}\n" + + ind(ind) + "}\n"; + } + private static String spanTreeSetter(String field) { return setter(field)+"SpanTrees"; } |