summaryrefslogtreecommitdiffstats
path: root/config-model/src/main/java/com/yahoo/documentmodel
diff options
context:
space:
mode:
authorJon Bratseth <bratseth@yahoo-inc.com>2016-06-15 23:09:44 +0200
committerJon Bratseth <bratseth@yahoo-inc.com>2016-06-15 23:09:44 +0200
commit72231250ed81e10d66bfe70701e64fa5fe50f712 (patch)
tree2728bba1131a6f6e5bdf95afec7d7ff9358dac50 /config-model/src/main/java/com/yahoo/documentmodel
Publish
Diffstat (limited to 'config-model/src/main/java/com/yahoo/documentmodel')
-rw-r--r--config-model/src/main/java/com/yahoo/documentmodel/DataTypeCollection.java15
-rw-r--r--config-model/src/main/java/com/yahoo/documentmodel/DataTypeRepo.java58
-rw-r--r--config-model/src/main/java/com/yahoo/documentmodel/DocumentTypeCollection.java13
-rw-r--r--config-model/src/main/java/com/yahoo/documentmodel/DocumentTypeRepo.java39
-rw-r--r--config-model/src/main/java/com/yahoo/documentmodel/NewDocumentType.java366
-rw-r--r--config-model/src/main/java/com/yahoo/documentmodel/VespaDocumentType.java39
6 files changed, 530 insertions, 0 deletions
diff --git a/config-model/src/main/java/com/yahoo/documentmodel/DataTypeCollection.java b/config-model/src/main/java/com/yahoo/documentmodel/DataTypeCollection.java
new file mode 100644
index 00000000000..822ddcd0da7
--- /dev/null
+++ b/config-model/src/main/java/com/yahoo/documentmodel/DataTypeCollection.java
@@ -0,0 +1,15 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.documentmodel;
+
+import com.yahoo.document.DataType;
+
+import java.util.Collection;
+
+/**
+ * @author <a href="mailto:balder@yahoo-inc.com">Henning Baldersheim</a>
+ */
+public interface DataTypeCollection {
+ public DataType getDataType(String name);
+ public DataType getDataType(int id);
+ public Collection<DataType> getTypes();
+}
diff --git a/config-model/src/main/java/com/yahoo/documentmodel/DataTypeRepo.java b/config-model/src/main/java/com/yahoo/documentmodel/DataTypeRepo.java
new file mode 100644
index 00000000000..6d332ba16fb
--- /dev/null
+++ b/config-model/src/main/java/com/yahoo/documentmodel/DataTypeRepo.java
@@ -0,0 +1,58 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.documentmodel;
+
+import com.yahoo.document.DataType;
+
+import java.util.Collection;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+/**
+ * @author <a href="mailto:balder@yahoo-inc.com">Henning Baldersheim</a>
+ */
+public class DataTypeRepo implements DataTypeCollection {
+ Map<Integer, DataType> typeById = new LinkedHashMap<>();
+ Map<String, DataType> typeByName = new LinkedHashMap<>();
+
+ public DataType getDataType(String name) {
+ return typeByName.get(name);
+ }
+
+ public DataType getDataType(int id) {
+ return typeById.get(id);
+ }
+
+ public Collection<DataType> getTypes() { return typeById.values(); }
+
+ public DataTypeRepo add(DataType type) {
+ if (typeByName.containsKey(type.getName()) ||
+ typeById.containsKey(type.getId()))
+ {
+ throw new IllegalStateException("Data type '" + type.getName() + "', id '" + type.getId() + "' is already registered.");
+ }
+ typeByName.put(type.getName(), type);
+ typeById.put(type.getId(), type);
+ return this;
+ }
+
+ public DataTypeRepo addAll(DataTypeCollection repo) {
+ for (DataType dataType : repo.getTypes()) {
+ add(dataType);
+ }
+ return this;
+ }
+
+ public DataTypeRepo replace(DataType type) {
+ if (!typeByName.containsKey(type.getName()) ||
+ !typeById.containsKey(type.getId()))
+ {
+ throw new IllegalStateException("Data type '" + type.getName() + "' is not registered.");
+ }
+ typeByName.remove(type.getName());
+ typeByName.put(type.getName(), type);
+ typeById.remove(type.getId());
+ typeById.put(type.getId(), type);
+ return this;
+ }
+
+}
diff --git a/config-model/src/main/java/com/yahoo/documentmodel/DocumentTypeCollection.java b/config-model/src/main/java/com/yahoo/documentmodel/DocumentTypeCollection.java
new file mode 100644
index 00000000000..6c71410c048
--- /dev/null
+++ b/config-model/src/main/java/com/yahoo/documentmodel/DocumentTypeCollection.java
@@ -0,0 +1,13 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.documentmodel;
+
+import java.util.Collection;
+
+/**
+ * @author <a href="mailto:balder@yahoo-inc.com">Henning Baldersheim</a>
+ */
+public interface DocumentTypeCollection {
+ public NewDocumentType getDocumentType(NewDocumentType.Name name);
+ public NewDocumentType getDocumentType(int id);
+ public Collection<NewDocumentType> getTypes();
+}
diff --git a/config-model/src/main/java/com/yahoo/documentmodel/DocumentTypeRepo.java b/config-model/src/main/java/com/yahoo/documentmodel/DocumentTypeRepo.java
new file mode 100644
index 00000000000..3585a12ac2f
--- /dev/null
+++ b/config-model/src/main/java/com/yahoo/documentmodel/DocumentTypeRepo.java
@@ -0,0 +1,39 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.documentmodel;
+
+import java.util.Collection;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+/**
+ * @author <a href="mailto:balder@yahoo-inc.com">Henning Baldersheim</a>
+ */
+public class DocumentTypeRepo implements DocumentTypeCollection {
+ final Map<Integer, NewDocumentType> typeById = new LinkedHashMap<>();
+ final Map<NewDocumentType.Name, NewDocumentType> typeByName = new LinkedHashMap<>();
+
+ public final NewDocumentType getDocumentType(String name) {
+ return typeByName.get(new NewDocumentType.Name(name));
+ }
+ public NewDocumentType getDocumentType(NewDocumentType.Name name) {
+ return typeByName.get(name);
+ }
+
+ public NewDocumentType getDocumentType(int id) {
+ return typeById.get(id);
+ }
+
+ public Collection<NewDocumentType> getTypes() { return typeById.values(); }
+
+ public DocumentTypeRepo add(NewDocumentType type) {
+ if (typeByName.containsKey(type.getFullName())) {
+ throw new IllegalStateException("Document type " + type.toString() + " is already registered");
+ }
+ if (typeById.containsKey(type.getFullName().getId())) {
+ throw new IllegalStateException("Document type " + type.toString() + " is already registered");
+ }
+ typeByName.put(type.getFullName(), type);
+ typeById.put(type.getFullName().getId(), type);
+ return this;
+ }
+}
diff --git a/config-model/src/main/java/com/yahoo/documentmodel/NewDocumentType.java b/config-model/src/main/java/com/yahoo/documentmodel/NewDocumentType.java
new file mode 100644
index 00000000000..51171e97704
--- /dev/null
+++ b/config-model/src/main/java/com/yahoo/documentmodel/NewDocumentType.java
@@ -0,0 +1,366 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.documentmodel;
+
+import com.yahoo.document.*;
+import com.yahoo.document.annotation.AnnotationType;
+import com.yahoo.document.annotation.AnnotationTypeRegistry;
+import com.yahoo.document.datatypes.FieldValue;
+import com.yahoo.searchdefinition.FieldSets;
+import com.yahoo.searchdefinition.Search;
+import com.yahoo.searchdefinition.document.FieldSet;
+import com.yahoo.searchdefinition.processing.BuiltInFieldSets;
+
+import java.util.*;
+
+/**
+ * TODO: What is this and why?
+ *
+ * @author <a href="mailto:balder@yahoo-inc.com">Henning Baldersheim</a>
+ */
+public final class NewDocumentType extends StructuredDataType implements DataTypeCollection {
+
+ /**
+ * TODO: What is this and why?
+ */
+ public static final class Name {
+
+ // TODO: privatize
+ final String name;
+ final int id;
+
+ public Name(String name) {
+ this(name.hashCode(),name);
+ }
+
+ public Name(int id,String name) {
+ this.id = id;
+ this.name = name;
+ }
+
+ public String toString() { return name; }
+
+ public final String getName() { return name; }
+
+ public final int getId() { return id; }
+
+ public int hashCode() { return name.hashCode(); }
+
+ public boolean equals(Object other) {
+ if ( ! (other instanceof Name)) return false;
+ return name.equals(((Name)other).getName());
+ }
+ }
+
+ private final Name name;
+ private final DataTypeRepo dataTypes = new DataTypeRepo();
+ private final Map<Integer, NewDocumentType> inherits = new LinkedHashMap<>();
+ private final AnnotationTypeRegistry annotations = new AnnotationTypeRegistry();
+ private final StructDataType header;
+ private final StructDataType body;
+ private final Set<FieldSet> fieldSets = new LinkedHashSet<>();
+
+ public NewDocumentType(Name name) {
+ this(name,
+ new StructDataType(name.getName() + ".header"),
+ new StructDataType(name.getName() + ".body"), new FieldSets());
+ }
+ public NewDocumentType(Name name, StructDataType header, StructDataType body, FieldSets fs) {
+ super(name.getName());
+ this.name = name;
+ this.header = header;
+ this.body = body;
+ if (fs != null) {
+ this.fieldSets.addAll(fs.userFieldSets().values());
+ for (FieldSet f : fs.builtInFieldSets().values()) {
+ if ((f.getName() != BuiltInFieldSets.INTERNAL_FIELDSET_NAME) &&
+ (f.getName() != BuiltInFieldSets.SEARCH_FIELDSET_NAME)) {
+ fieldSets.add(f);
+ }
+ }
+ }
+ }
+
+ public Name getFullName() {
+ return name;
+ }
+
+ public DataType getHeader() { return header; }
+ public DataType getBody() { return body; }
+ public Collection<NewDocumentType> getInherited() { return inherits.values(); }
+ public NewDocumentType getInherited(Name inherited) { return inherits.get(inherited.getId()); }
+ public NewDocumentType removeInherited(Name inherited) { return inherits.remove(inherited.getId()); }
+
+ /**
+ * Data type of the header fields of this and all inherited document types
+ * @return merged {@link StructDataType}
+ */
+ public StructDataType allHeader() {
+ StructDataType ret = new StructDataType(header.getName());
+ for (Field f : header.getFields()) {
+ ret.addField(f);
+ }
+ for (NewDocumentType inherited : getInherited()) {
+ for (Field f : ((StructDataType) inherited.getHeader()).getFields()) {
+ ret.addField(f);
+ }
+ }
+ return ret;
+ }
+
+ /**
+ * Data type of the body fields of this and all inherited document types
+ * @return merged {@link StructDataType}
+ */
+ public StructDataType allBody() {
+ StructDataType ret = new StructDataType(body.getName());
+ for (Field f : body.getFields()) {
+ ret.addField(f);
+ }
+ for (NewDocumentType inherited : getInherited()) {
+ for (Field f : ((StructDataType) inherited.getBody()).getFields()) {
+ ret.addField(f);
+ }
+ }
+ return ret;
+ }
+
+ @Override
+ public Class getValueClass() {
+ return Document.class;
+ }
+
+ @Override
+ public boolean isValueCompatible(FieldValue value) {
+ if (!(value instanceof Document)) {
+ return false;
+ }
+ /** Temporary disabled due to clash with document and covariant return type
+ Document doc = (Document) value;
+ if (((NewDocumentType) doc.getDataType()).inherits(this)) {
+ //the value is of this type; or the supertype of the value is of this type, etc....
+ return true;
+ }
+ */
+ return false;
+ }
+
+ private boolean verifyInheritance(NewDocumentType inherited) {
+ for (Field f : getFields()) {
+ Field inhF = inherited.getField(f.getName());
+ if (inhF != null && !inhF.equals(f)) {
+ throw new IllegalArgumentException("Inherited document '" + inherited.toString() + "' already contains field '" +
+ inhF.getName() + "'. Can not override with '" + f.getName() + "'.");
+ }
+ }
+ for (Field f : inherited.getAllFields()) {
+ for (NewDocumentType side : inherits.values()) {
+ Field sideF = side.getField(f.getName());
+ if (sideF != null && !sideF.equals(f)) {
+ throw new IllegalArgumentException("Inherited document '" + side.toString() + "' already contains field '" +
+ sideF.getName() + "'. Document '" + inherited.toString() + "' also defines field '" + f.getName() +
+ "'.Multiple inheritance must be disjunctive.");
+ }
+ }
+ }
+ return true;
+ }
+ public void inherit(NewDocumentType inherited) {
+ if ( ! inherits.containsKey(inherited.getId())) {
+ verifyInheritance(inherited);
+ inherits.put(inherited.getId(), inherited);
+ }
+ }
+ public boolean inherits(NewDocumentType superType) {
+ if (getId() == superType.getId()) return true;
+ for (NewDocumentType type : inherits.values()) {
+ if (type.inherits(superType)) return true;
+ }
+ return false;
+ }
+
+ @Override
+ public Field getField(String name) {
+ Field field = header.getField(name);
+ if (field == null) {
+ field = body.getField(name);
+ }
+ if (field == null) {
+ for (NewDocumentType inheritedType : inherits.values()) {
+ field = inheritedType.getField(name);
+ if (field != null) {
+ return field;
+ }
+ }
+ }
+ return field;
+ }
+
+ public boolean containsField(String fieldName) {
+ return getField(fieldName) != null;
+ }
+
+ @Override
+ public Field getField(int id) {
+ Field field = header.getField(id);
+ if (field == null) {
+ field = body.getField(id);
+ }
+ if (field == null) {
+ for (NewDocumentType inheritedType : inherits.values()) {
+ field = inheritedType.getField(id);
+ if (field != null) {
+ return field;
+ }
+ }
+ }
+ return field;
+ }
+
+ public Collection<Field> getAllFields() {
+ Collection<Field> collection = new LinkedList<>();
+
+ for (NewDocumentType type : inherits.values()) {
+ collection.addAll(type.getAllFields());
+ }
+
+ collection.addAll(header.getFields());
+ collection.addAll(body.getFields());
+ return Collections.unmodifiableCollection(collection);
+ }
+
+ public Collection<Field> getFields() {
+ Collection<Field> collection = new LinkedList<>();
+ collection.addAll(header.getFields());
+ collection.addAll(body.getFields());
+ return Collections.unmodifiableCollection(collection);
+ }
+
+ @Override
+ public Document createFieldValue() {
+ return new Document(null, (DocumentId)null);
+ }
+
+ @Override
+ public Collection<DataType> getTypes() {
+ return dataTypes.getTypes();
+ }
+
+ public DataTypeCollection getAllTypes() {
+ DataTypeRepo repo = new DataTypeRepo();
+ Set<Name> seen = new HashSet<>();
+ Deque<NewDocumentType> stack = new LinkedList<>();
+ stack.push(this);
+ while (!stack.isEmpty()) {
+ NewDocumentType docType = stack.pop();
+ if (seen.contains(docType.name)) {
+ continue; // base type
+ }
+ seen.add(docType.name);
+ for (DataType dataType : docType.getTypes()) {
+ if (repo.getDataType(dataType.getId()) == null) {
+ repo.add(dataType);
+ }
+ }
+ stack.addAll(docType.inherits.values());
+ }
+ return repo;
+ }
+
+ public Collection<AnnotationType> getAnnotations() { return annotations.getTypes().values(); }
+ public Collection<AnnotationType> getAllAnnotations() {
+ Collection<AnnotationType> collection = new LinkedList<>();
+
+ for (NewDocumentType type : inherits.values()) {
+ collection.addAll(type.getAllAnnotations());
+ }
+ collection.addAll(getAnnotations());
+
+ return Collections.unmodifiableCollection(collection);
+ }
+
+ public DataType getDataType(String name) {
+ return dataTypes.getDataType(name);
+ }
+ public DataType getDataType(int id) {
+ return dataTypes.getDataType(id);
+ }
+ public DataType getDataTypeRecursive(String name) {
+ DataType a = dataTypes.getDataType(name);
+ if (a != null) {
+ return a;
+ } else {
+ for (NewDocumentType dt : getInherited()) {
+ a = dt.getDataTypeRecursive(name);
+ if (a != null) {
+ return a;
+ }
+ }
+ }
+ return null;
+ }
+
+ public DataType getDataTypeRecursive(int id) {
+ DataType a = dataTypes.getDataType(id);
+ if (a != null) {
+ return a;
+ } else {
+ for (NewDocumentType dt : getInherited()) {
+ a = dt.getDataTypeRecursive(id);
+ if (a != null) {
+ return a;
+ }
+ }
+ }
+ return null;
+ }
+
+ public AnnotationType getAnnotationType(String name) {
+ AnnotationType a = annotations.getType(name);
+ if (a != null) {
+ return a;
+ } else {
+ for (NewDocumentType dt : getInherited()) {
+ a = dt.getAnnotationType(name);
+ if (a != null) {
+ return a;
+ }
+ }
+ }
+ return null;
+ }
+ public AnnotationType getAnnotationType(int id) {
+ AnnotationType a = annotations.getType(id);
+ if (a != null) {
+ return a;
+ } else {
+ for (NewDocumentType dt : getInherited()) {
+ a = dt.getAnnotationType(id);
+ if (a != null) {
+ return a;
+ }
+ }
+ }
+ return null;
+ }
+
+ public NewDocumentType add(AnnotationType type) {
+ annotations.register(type);
+ return this;
+ }
+ public NewDocumentType add(DataType type) {
+ dataTypes.add(type);
+ return this;
+ }
+ public NewDocumentType replace(DataType type) {
+ dataTypes.replace(type);
+ return this;
+ }
+
+ /**
+ * The field sets defined for this type and its {@link Search}
+ * @return fieldsets
+ */
+ public Set<FieldSet> getFieldSets() {
+ return Collections.unmodifiableSet(fieldSets);
+ }
+}
diff --git a/config-model/src/main/java/com/yahoo/documentmodel/VespaDocumentType.java b/config-model/src/main/java/com/yahoo/documentmodel/VespaDocumentType.java
new file mode 100644
index 00000000000..bf8ec8d3da7
--- /dev/null
+++ b/config-model/src/main/java/com/yahoo/documentmodel/VespaDocumentType.java
@@ -0,0 +1,39 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.documentmodel;
+
+import com.yahoo.document.DataType;
+import com.yahoo.document.DataTypeName;
+import com.yahoo.document.PositionDataType;
+
+/**
+ * This class represents the builtin 'doument' document type that all other documenttypes inherits.
+ * Remember that changes here must be compatible. Changes to types of fields can not be done here.
+ * This must also match the mirroring class in c++.
+ *
+ * @author <a href="mailto:balder@yahoo-inc.com">Henning Baldersheim</a>
+ */
+public class VespaDocumentType {
+
+ public static NewDocumentType INSTANCE = newInstance();
+
+ public static DataTypeName NAME = new DataTypeName("document");
+
+ private static NewDocumentType newInstance() {
+ NewDocumentType vespa = new NewDocumentType(new NewDocumentType.Name(8, "document"));
+ vespa.add(DataType.BYTE);
+ vespa.add(DataType.INT);
+ vespa.add(DataType.LONG);
+ vespa.add(DataType.STRING);
+ vespa.add(DataType.RAW);
+ vespa.add(DataType.TAG);
+ vespa.add(DataType.FLOAT);
+ vespa.add(DataType.DOUBLE);
+ vespa.add(DataType.DOCUMENT);
+ vespa.add(PositionDataType.INSTANCE);
+ vespa.add(DataType.URI);
+ vespa.add(DataType.PREDICATE);
+ vespa.add(DataType.TENSOR);
+ return vespa;
+ }
+
+}