summaryrefslogtreecommitdiffstats
path: root/document
diff options
context:
space:
mode:
authorHenning Baldersheim <balder@yahoo-inc.com>2019-08-28 10:00:21 +0200
committerHenning Baldersheim <balder@yahoo-inc.com>2019-08-28 10:00:21 +0200
commit178953855fc944b2861954dd558e4bd397c04b00 (patch)
treeb78d9782c1d3b0a1052292247a05122adca37dcf /document
parent18a0e65a0cdad8c9afc0dd16fac1e0941e67aa30 (diff)
Only expose explicit fields in the document.
Also build all fieldSets when constructing the document type.
Diffstat (limited to 'document')
-rw-r--r--document/abi-spec.json4
-rwxr-xr-xdocument/src/main/java/com/yahoo/document/DocumentType.java63
-rw-r--r--document/src/main/java/com/yahoo/document/DocumentTypeManagerConfigurer.java8
-rw-r--r--document/src/test/java/com/yahoo/document/DocumentTypeTestCase.java45
4 files changed, 95 insertions, 25 deletions
diff --git a/document/abi-spec.json b/document/abi-spec.json
index d6ee31695da..6ce2543b4c2 100644
--- a/document/abi-spec.json
+++ b/document/abi-spec.json
@@ -437,6 +437,7 @@
"protected void register(com.yahoo.document.DocumentTypeManager, java.util.List)",
"public boolean isA(java.lang.String)",
"public void addField(com.yahoo.document.Field)",
+ "public void addFieldSets(java.util.Map)",
"public com.yahoo.document.Field addField(java.lang.String, com.yahoo.document.DataType)",
"public com.yahoo.document.Field addHeaderField(java.lang.String, com.yahoo.document.DataType)",
"public void inherit(com.yahoo.document.DocumentType)",
@@ -450,6 +451,8 @@
"public com.yahoo.document.Field removeField(java.lang.String)",
"public java.util.Collection getFields()",
"public java.util.Set fieldSet()",
+ "public java.util.Set fieldSetAll()",
+ "public java.util.Set fieldSet(java.lang.String)",
"public java.util.Iterator fieldIteratorThisTypeOnly()",
"public boolean equals(java.lang.Object)",
"public int hashCode()",
@@ -462,6 +465,7 @@
"public bridge synthetic java.lang.Object clone()"
],
"fields": [
+ "public static final java.lang.String DOCUMENT",
"public static final int classId"
]
},
diff --git a/document/src/main/java/com/yahoo/document/DocumentType.java b/document/src/main/java/com/yahoo/document/DocumentType.java
index 3a99c216c3f..2c9fe7b30d1 100755
--- a/document/src/main/java/com/yahoo/document/DocumentType.java
+++ b/document/src/main/java/com/yahoo/document/DocumentType.java
@@ -12,8 +12,11 @@ import com.yahoo.vespa.objects.Serializer;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
@@ -32,10 +35,13 @@ import java.util.Set;
// TODO: Remove header/body concept on Vespa 8
public class DocumentType extends StructuredDataType {
+ private static final String ALL = "[all]";
+ public static final String DOCUMENT = "[document]";
public static final int classId = registerClass(Ids.document + 58, DocumentType.class);
private StructDataType headerType;
private StructDataType bodyType;
private List<DocumentType> inherits = new ArrayList<>(1);
+ private Map<String, Set<Field>> fieldSets = new HashMap<>();
/**
* Creates a new document type and registers it with the document type manager.
@@ -135,7 +141,7 @@ public class DocumentType extends StructuredDataType {
header.clearFields();
body.clearFields();
- for (Field field : fieldSet()) {
+ for (Field field : getAllUniqueFields()) {
(field.isHeader() ? header : body).addField(field);
}
headerType.assign(header);
@@ -180,6 +186,30 @@ public class DocumentType extends StructuredDataType {
struct.addField(field);
}
+ // Do not use, public only for testing
+ public void addFieldSets(Map<String, Collection<String>> fieldSets) {
+ for (Map.Entry<String, Collection<String>> entry : fieldSets.entrySet()) {
+
+ Set<Field> fields = new LinkedHashSet<>(entry.getValue().size());
+ for (DocumentType parent : inherits) {
+ Set<Field> parentFieldSet = parent.fieldSet(entry.getKey());
+ if (parentFieldSet != null) {
+ fields.addAll(parentFieldSet);
+ }
+ }
+ for (Field orderedField : getAllUniqueFields()) {
+ if (entry.getValue().contains(orderedField.getName())) {
+ fields.add(orderedField);
+ }
+ }
+
+ this.fieldSets.put(entry.getKey(), ImmutableSet.copyOf(fields));
+ }
+ if ( ! this.fieldSets.containsKey(ALL)) {
+ this.fieldSets.put(ALL, getAllUniqueFields());
+ }
+ }
+
/**
* Adds a new body field to this document type and returns the new field object
*
@@ -249,7 +279,7 @@ public class DocumentType extends StructuredDataType {
* TODO Add strict type checking no duplicate fields are allowed
*/
private void verifyTypeConsistency(DocumentType superType) {
- for (Field f : fieldSet()) {
+ for (Field f : getAllUniqueFields()) {
Field supField = superType.getField(f.getName());
if (supField != null) {
if (!f.getDataType().equals(supField.getDataType())) {
@@ -341,9 +371,6 @@ public class DocumentType extends StructuredDataType {
return getField(name) != null;
}
- //@Override
-
-
public int getFieldCount() {
return headerType.getFieldCount() + bodyType.getFieldCount();
}
@@ -383,6 +410,14 @@ public class DocumentType extends StructuredDataType {
return ImmutableList.copyOf(collection);
}
+ private Set<Field> getAllUniqueFields() {
+ Map<String, Field> map = new LinkedHashMap<>();
+ for (Field field : getFields()) { // Uniqify on field name
+ map.put(field.getName(), field);
+ }
+ return ImmutableSet.copyOf(map.values());
+ }
+
/**
* <p>Returns an ordered set snapshot of all fields of this documenttype,
* <i>except the fields of Document</i>.
@@ -400,11 +435,19 @@ public class DocumentType extends StructuredDataType {
* @return an unmodifiable snapshot of the fields in this type
*/
public Set<Field> fieldSet() {
- Map<String, Field> map = new LinkedHashMap<>();
- for (Field field : getFields()) { // Uniqify on field name
- map.put(field.getName(), field);
- }
- return ImmutableSet.copyOf(map.values());
+ return fieldSet(DOCUMENT);
+ }
+
+ /**
+ * This is identical to @link fieldSet, but in addition extra hidden synthetic fields are returned.
+ * @return an unmodifiable snapshot of the all fields in this type
+ */
+ public Set<Field> fieldSetAll() {
+ return fieldSet(ALL);
+ }
+
+ public Set<Field> fieldSet(String name) {
+ return fieldSets.get(name);
}
/**
diff --git a/document/src/main/java/com/yahoo/document/DocumentTypeManagerConfigurer.java b/document/src/main/java/com/yahoo/document/DocumentTypeManagerConfigurer.java
index be5c6856ee5..154c25880a9 100644
--- a/document/src/main/java/com/yahoo/document/DocumentTypeManagerConfigurer.java
+++ b/document/src/main/java/com/yahoo/document/DocumentTypeManagerConfigurer.java
@@ -8,6 +8,9 @@ import com.yahoo.document.annotation.AnnotationReferenceDataType;
import com.yahoo.document.annotation.AnnotationType;
import com.yahoo.log.LogLevel;
import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
import java.util.logging.Logger;
/**
@@ -152,6 +155,11 @@ public class DocumentTypeManagerConfigurer implements ConfigSubscriber.SingleSub
}
type.inherit(parentType);
}
+ Map<String, Collection<String>> fieldSets = new HashMap<>(doc.fieldsets().size());
+ for (Map.Entry<String, DocumentmanagerConfig.Datatype.Documenttype.Fieldsets> entry: doc.fieldsets().entrySet()) {
+ fieldSets.put(entry.getKey(), entry.getValue().fields());
+ }
+ type.addFieldSets(fieldSets);
manager.register(type);
}
diff --git a/document/src/test/java/com/yahoo/document/DocumentTypeTestCase.java b/document/src/test/java/com/yahoo/document/DocumentTypeTestCase.java
index abbfd31b778..47c7fe71343 100644
--- a/document/src/test/java/com/yahoo/document/DocumentTypeTestCase.java
+++ b/document/src/test/java/com/yahoo/document/DocumentTypeTestCase.java
@@ -3,10 +3,13 @@ package com.yahoo.document;
import org.junit.Test;
+import java.util.Arrays;
+import java.util.Collections;
import java.util.Iterator;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
@@ -29,35 +32,49 @@ public class DocumentTypeTestCase {
}
@Test
+ public void testFieldSets() {
+ DocumentType root = new DocumentType("root");
+ root.addField("rootfield1", DataType.STRING);
+ root.addField("rootfield2", DataType.STRING);
+ root.addField("rootfield3", DataType.STRING);
+ root.addFieldSets(Collections.singletonMap(DocumentType.DOCUMENT, Arrays.asList("rootfield2")));
+ assertEquals(1, root.fieldSet().size());
+ assertEquals("rootfield2", root.fieldSet().iterator().next().getName());
+ assertEquals(3, root.fieldSetAll().size());
+ }
+
+ @Test
public void testInheritance() {
DocumentTypeManager typeManager = new DocumentTypeManager();
- DocumentType child = new DocumentType("child");
- Iterator inherited;
-
- child.addField("childfield", DataType.INT);
- child.addField("overridden", DataType.STRING);
+ DocumentType root = new DocumentType("root");
+ root.addField("rootfield", DataType.STRING);
+ root.addFieldSets(Collections.singletonMap(DocumentType.DOCUMENT, Arrays.asList("rootfield")));
DocumentType parent1 = new DocumentType("parent1");
parent1.addField("overridden", DataType.STRING);
parent1.addField("parent1field", DataType.STRING);
- child.inherit(parent1);
+ parent1.inherit(root);
+ parent1.addFieldSets(Collections.singletonMap(DocumentType.DOCUMENT, Arrays.asList("parent1field", "overridden")));
DocumentType parent2 = new DocumentType("parent2");
parent2.addField("parent2field", DataType.STRING);
- child.inherit(parent2);
-
- DocumentType root = new DocumentType("root");
- root.addField("rootfield", DataType.STRING);
- parent1.inherit(root);
parent2.inherit(root);
+ parent2.addFieldSets(Collections.singletonMap(DocumentType.DOCUMENT, Arrays.asList("parent2field")));
+
+ DocumentType child = new DocumentType("child");
+ child.addField("childfield", DataType.INT);
+ child.addField("overridden", DataType.STRING);
+ child.inherit(parent1);
+ child.inherit(parent2);
+ child.addFieldSets(Collections.singletonMap(DocumentType.DOCUMENT, Arrays.asList("childfield", "overridden")));
typeManager.register(root);
typeManager.register(parent1);
typeManager.register(parent2);
typeManager.register(child);
- inherited = child.getInheritedTypes().iterator();
+ Iterator inherited = child.getInheritedTypes().iterator();
assertEquals(parent1, inherited.next());
assertEquals(parent2, inherited.next());
assertTrue(!inherited.hasNext());
@@ -95,9 +112,7 @@ public class DocumentTypeTestCase {
assertFalse(fields.hasNext());
- assert(child.getField("rootfield") != null);
-
- // TODO: Test uninheriting
+ assertNotNull(child.getField("rootfield"));
}
}