aboutsummaryrefslogtreecommitdiffstats
path: root/config-model
diff options
context:
space:
mode:
authorGeir Storli <geirstorli@yahoo.no>2017-01-23 16:58:55 +0100
committerGitHub <noreply@github.com>2017-01-23 16:58:55 +0100
commita5a30171965cea021761e629b45a837d2d1c4629 (patch)
tree184dbf35c633c02d6ceadb694d38f34a9f39e3a7 /config-model
parentf316bb001a345b259aa15b3a7cb5c07ca8c0f5c0 (diff)
parent4960f7ce8b00943a56dd750cf0b6e9fe5e5025a4 (diff)
Merge pull request #1579 from yahoo/geirst/parsing-of-imported-fields-in-sd-file
Add parsing of imported fields in SD file.
Diffstat (limited to 'config-model')
-rw-r--r--config-model/src/main/java/com/yahoo/searchdefinition/Search.java6
-rw-r--r--config-model/src/main/java/com/yahoo/searchdefinition/document/ImportedFields.java24
-rw-r--r--config-model/src/main/java/com/yahoo/searchdefinition/document/TemporaryFieldReference.java33
-rw-r--r--config-model/src/main/java/com/yahoo/searchdefinition/document/TemporaryImportedField.java29
-rw-r--r--config-model/src/main/javacc/SDParser.jj36
-rw-r--r--config-model/src/test/java/com/yahoo/searchdefinition/RankingConstantTest.java4
-rw-r--r--config-model/src/test/java/com/yahoo/searchdefinition/TestUtils.java12
-rw-r--r--config-model/src/test/java/com/yahoo/searchdefinition/processing/ImportedFieldsTestCase.java60
8 files changed, 200 insertions, 4 deletions
diff --git a/config-model/src/main/java/com/yahoo/searchdefinition/Search.java b/config-model/src/main/java/com/yahoo/searchdefinition/Search.java
index 9032f913d0b..710f49dddb6 100644
--- a/config-model/src/main/java/com/yahoo/searchdefinition/Search.java
+++ b/config-model/src/main/java/com/yahoo/searchdefinition/Search.java
@@ -70,6 +70,8 @@ public class Search implements Serializable {
// Ranking constants defined inside this s.d.
private Map<String, RankingConstant> rankingConstants = new HashMap<>();
+ private ImportedFields importedFields = new ImportedFields();
+
private ApplicationPackage sourceApplication;
/**
@@ -154,6 +156,10 @@ public class Search implements Serializable {
return rankingConstants.values();
}
+ public ImportedFields importedFields() {
+ return importedFields;
+ }
+
/**
* Gets a document from this search definition
*
diff --git a/config-model/src/main/java/com/yahoo/searchdefinition/document/ImportedFields.java b/config-model/src/main/java/com/yahoo/searchdefinition/document/ImportedFields.java
new file mode 100644
index 00000000000..01d14104d2b
--- /dev/null
+++ b/config-model/src/main/java/com/yahoo/searchdefinition/document/ImportedFields.java
@@ -0,0 +1,24 @@
+// Copyright 2017 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.searchdefinition.document;
+
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+/**
+ * A set of fields that are imported from referenced document types.
+ *
+ * @author geirst
+ */
+public class ImportedFields {
+
+ private final Map<String, TemporaryImportedField> fields = new LinkedHashMap<>();
+
+ public void add(TemporaryImportedField importedField) {
+ fields.put(importedField.fieldName(), importedField);
+ }
+
+ public Map<String, TemporaryImportedField> fields() {
+ return Collections.unmodifiableMap(fields);
+ }
+}
diff --git a/config-model/src/main/java/com/yahoo/searchdefinition/document/TemporaryFieldReference.java b/config-model/src/main/java/com/yahoo/searchdefinition/document/TemporaryFieldReference.java
new file mode 100644
index 00000000000..2dea3f9bf88
--- /dev/null
+++ b/config-model/src/main/java/com/yahoo/searchdefinition/document/TemporaryFieldReference.java
@@ -0,0 +1,33 @@
+// Copyright 2017 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.searchdefinition.document;
+
+/**
+ * Temporary reference to a field in another document type.
+ *
+ * After all SD files are parsed this temporary reference can be validated and connected
+ * to the actual field instance in the referenced document type.
+ *
+ * @author geirst
+ */
+public class TemporaryFieldReference {
+
+ private final String refFieldName;
+ private final String fieldNameInRefType;
+
+ /**
+ * @param refFieldName points to a field of type reference (in this document type).
+ * @param fieldNameInRefType points to a field in the referenced document type.
+ */
+ public TemporaryFieldReference(String refFieldName, String fieldNameInRefType) {
+ this.refFieldName = refFieldName;
+ this.fieldNameInRefType = fieldNameInRefType;
+ }
+
+ public String refFieldName() {
+ return refFieldName;
+ }
+
+ public String fieldNameInRefType() {
+ return fieldNameInRefType;
+ }
+}
diff --git a/config-model/src/main/java/com/yahoo/searchdefinition/document/TemporaryImportedField.java b/config-model/src/main/java/com/yahoo/searchdefinition/document/TemporaryImportedField.java
new file mode 100644
index 00000000000..23a5e05c55f
--- /dev/null
+++ b/config-model/src/main/java/com/yahoo/searchdefinition/document/TemporaryImportedField.java
@@ -0,0 +1,29 @@
+// Copyright 2017 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.searchdefinition.document;
+
+/**
+ * Temporary field that is imported from a field in a referenced document type.
+ *
+ * After all SD files are parsed this temporary field can be validated and connected
+ * to the actual field instance in the referenced document type.
+ *
+ * @author geirst
+ */
+public class TemporaryImportedField {
+
+ private final String fieldName;
+ private final TemporaryFieldReference reference;
+
+ public TemporaryImportedField(String fieldName, TemporaryFieldReference reference) {
+ this.fieldName = fieldName;
+ this.reference = reference;
+ }
+
+ public String fieldName() {
+ return fieldName;
+ }
+
+ public TemporaryFieldReference reference() {
+ return reference;
+ }
+}
diff --git a/config-model/src/main/javacc/SDParser.jj b/config-model/src/main/javacc/SDParser.jj
index 30b9b77f368..a5d1af6b4cb 100644
--- a/config-model/src/main/javacc/SDParser.jj
+++ b/config-model/src/main/javacc/SDParser.jj
@@ -60,6 +60,7 @@ import com.yahoo.search.query.ranking.Diversity;
import java.util.Map;
import java.util.LinkedHashMap;
import java.util.logging.Level;
+import org.apache.commons.lang.StringUtils;
/**
* A search definition parser
@@ -193,6 +194,8 @@ TOKEN :
| < FIELDS: "fields" >
| < FIELDSET: "fieldset" >
| < STRUCTFIELD: "struct-field" >
+| < IMPORT: "import" >
+| < AS: "as" >
| < INDEXING: "indexing" >
| < SUMMARYTO: "summary-to" >
| < DOCUMENTSUMMARY: "document-summary" >
@@ -421,7 +424,8 @@ Object rootSearchItem(Search search) : { }
| useDocument(search)
| structOutside(search)
| annotationOutside(search)
- | fieldSet(search) )
+ | fieldSet(search)
+ | importField(search) )
{ return null; }
}
@@ -2386,6 +2390,34 @@ TensorType tensorType(String errorMessage) :
}
}
+void importField(Search search) :
+{
+ TemporaryFieldReference reference;
+ String fieldName;
+}
+{
+ <IMPORT> <FIELD> reference = fieldReference() <AS> fieldName = identifier() lbrace()
+ <RBRACE>
+ {
+ search.importedFields().add(new TemporaryImportedField(fieldName, reference));
+ }
+}
+
+TemporaryFieldReference fieldReference() :
+{
+ String fieldRefSpec;
+}
+{
+ fieldRefSpec = identifier()
+ {
+ if (StringUtils.countMatches(fieldRefSpec, ".") != 1) {
+ throw new IllegalArgumentException("Illegal field reference spec '" + fieldRefSpec + "': Does not include a single '.'");
+ }
+ int indexOfDot = fieldRefSpec.indexOf('.');
+ return new TemporaryFieldReference(fieldRefSpec.substring(0, indexOfDot), fieldRefSpec.substring(indexOfDot + 1));
+ }
+}
+
/**
* This rule consumes an expression token and returns its image.
*
@@ -2416,6 +2448,7 @@ String identifier() : { }
| <ANNOTATIONREFERENCE>
| <ARITY>
| <ARRAY>
+ | <AS>
| <ASCENDING>
| <ATTRIBUTE>
| <BODY>
@@ -2454,6 +2487,7 @@ String identifier() : { }
| <IDENTICAL>
| <IDENTIFIER>
| <IGNOREDEFAULTRANKFEATURES>
+ | <IMPORT>
| <INDEX>
| <INDEXING>
| <INDEXINGREWRITE>
diff --git a/config-model/src/test/java/com/yahoo/searchdefinition/RankingConstantTest.java b/config-model/src/test/java/com/yahoo/searchdefinition/RankingConstantTest.java
index a208ac2dec0..aa65cca1b6a 100644
--- a/config-model/src/test/java/com/yahoo/searchdefinition/RankingConstantTest.java
+++ b/config-model/src/test/java/com/yahoo/searchdefinition/RankingConstantTest.java
@@ -8,6 +8,7 @@ import java.util.Iterator;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
+import static com.yahoo.searchdefinition.TestUtils.joinLines;
/**
* @author gjoranv
@@ -101,7 +102,4 @@ public class RankingConstantTest {
assertEquals("simplename", constant.getFileName());
}
- private static String joinLines(String... lines) {
- return String.join("\n", lines);
- }
}
diff --git a/config-model/src/test/java/com/yahoo/searchdefinition/TestUtils.java b/config-model/src/test/java/com/yahoo/searchdefinition/TestUtils.java
new file mode 100644
index 00000000000..d2c963d814d
--- /dev/null
+++ b/config-model/src/test/java/com/yahoo/searchdefinition/TestUtils.java
@@ -0,0 +1,12 @@
+// Copyright 2017 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.searchdefinition;
+
+/**
+ * @author geirst
+ */
+public class TestUtils {
+
+ public static String joinLines(String... lines) {
+ return String.join("\n", lines);
+ }
+}
diff --git a/config-model/src/test/java/com/yahoo/searchdefinition/processing/ImportedFieldsTestCase.java b/config-model/src/test/java/com/yahoo/searchdefinition/processing/ImportedFieldsTestCase.java
new file mode 100644
index 00000000000..434cfd72136
--- /dev/null
+++ b/config-model/src/test/java/com/yahoo/searchdefinition/processing/ImportedFieldsTestCase.java
@@ -0,0 +1,60 @@
+// Copyright 2017 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.searchdefinition.processing;
+
+import com.yahoo.searchdefinition.Search;
+import com.yahoo.searchdefinition.SearchBuilder;
+import com.yahoo.searchdefinition.document.TemporaryImportedField;
+import com.yahoo.searchdefinition.parser.ParseException;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+
+import static org.junit.Assert.assertEquals;
+import static com.yahoo.searchdefinition.TestUtils.joinLines;
+
+/**
+ * @author geirst
+ */
+public class ImportedFieldsTestCase {
+
+ @Test
+ public void require_that_imported_fields_can_be_parsed_from_sd_file() throws ParseException {
+ Search search = build(joinLines(
+ "search ad {",
+ " document ad {}",
+ " import field campaign.budget as budget {}",
+ " import field person.name as sales_person {}",
+ "}"));
+ assertEquals(2, search.importedFields().fields().size());
+ assertSearchContainsTemporaryImportedField("budget", "campaign", "budget", search);
+ assertSearchContainsTemporaryImportedField("sales_person", "person", "name", search);
+ }
+
+ @Rule
+ public ExpectedException exception = ExpectedException.none();
+
+ @Test
+ public void require_that_field_reference_spec_must_include_dot() throws ParseException {
+ exception.expect(IllegalArgumentException.class);
+ exception.expectMessage("Illegal field reference spec 'campaignbudget': Does not include a single '.'");
+ build(joinLines(
+ "search ad {",
+ " document ad {}",
+ " import field campaignbudget as budget {}",
+ "}"));
+ }
+
+ private static Search build(String sdContent) throws ParseException {
+ SearchBuilder builder = new SearchBuilder();
+ builder.importString(sdContent);
+ builder.build();
+ return builder.getSearch();
+ }
+
+ private static void assertSearchContainsTemporaryImportedField(String fieldName, String refFieldName, String fieldNameInRefType, Search search) {
+ TemporaryImportedField importedField = search.importedFields().fields().get(fieldName);
+ assertEquals(fieldName, importedField.fieldName());
+ assertEquals(refFieldName, importedField.reference().refFieldName());
+ assertEquals(fieldNameInRefType, importedField.reference().fieldNameInRefType());
+ }
+}