aboutsummaryrefslogtreecommitdiffstats
path: root/container-search
diff options
context:
space:
mode:
authorJon Bratseth <bratseth@oath.com>2018-01-31 17:36:21 +0100
committerJon Bratseth <bratseth@oath.com>2018-01-31 17:36:21 +0100
commitc56889931e1547a6a6db420a3c886ddf03f5bd6e (patch)
treea718a9bbacf236c54c8164def703f4e108e7287d /container-search
parent2c25a02adbe644b3f50dc44252c6b61974d0c8d6 (diff)
Canonicalize features
This allows us to find the type of features referenced in ranking expressions regardless of the form they are written in.
Diffstat (limited to 'container-search')
-rw-r--r--container-search/src/main/java/com/yahoo/search/query/profile/config/QueryProfileXMLReader.java229
1 files changed, 119 insertions, 110 deletions
diff --git a/container-search/src/main/java/com/yahoo/search/query/profile/config/QueryProfileXMLReader.java b/container-search/src/main/java/com/yahoo/search/query/profile/config/QueryProfileXMLReader.java
index 095d83d2887..eb4a0ad6be4 100644
--- a/container-search/src/main/java/com/yahoo/search/query/profile/config/QueryProfileXMLReader.java
+++ b/container-search/src/main/java/com/yahoo/search/query/profile/config/QueryProfileXMLReader.java
@@ -21,7 +21,6 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
-import java.util.logging.Logger;
/**
* A class which imports query profiles and types from XML files
@@ -30,8 +29,6 @@ import java.util.logging.Logger;
*/
public class QueryProfileXMLReader {
- private static Logger logger=Logger.getLogger(QueryProfileXMLReader.class.getName());
-
/**
* Reads all query profile xml files in a given directory,
* and all type xml files from the immediate subdirectory "types/" (if any)
@@ -42,8 +39,8 @@ public class QueryProfileXMLReader {
List<NamedReader> queryProfileReaders = new ArrayList<>();
List<NamedReader> queryProfileTypeReaders = new ArrayList<>();
try {
- File dir=new File(directory);
- if ( !dir.isDirectory() ) throw new IllegalArgumentException("Could not read query profiles: '" +
+ File dir = new File(directory);
+ if ( ! dir.isDirectory() ) throw new IllegalArgumentException("Could not read query profiles: '" +
directory + "' is not a valid directory.");
for (File file : sortFiles(dir)) {
@@ -100,21 +97,20 @@ public class QueryProfileXMLReader {
}
public List<Element> createQueryProfileTypes(List<NamedReader> queryProfileTypeReaders, QueryProfileTypeRegistry registry) {
- List<Element> queryProfileTypeElements=new ArrayList<>(queryProfileTypeReaders.size());
+ List<Element> queryProfileTypeElements = new ArrayList<>(queryProfileTypeReaders.size());
for (NamedReader reader : queryProfileTypeReaders) {
- Element root=XML.getDocument(reader).getDocumentElement();
+ Element root = XML.getDocument(reader).getDocumentElement();
if ( ! root.getNodeName().equals("query-profile-type")) {
- logger.info("Ignoring '" + reader.getName() +
- "': Expected XML root element 'query-profile-type' but was '" + root.getNodeName() + "'");
- continue;
+ throw new IllegalArgumentException("Root tag in '" + reader.getName() +
+ "' must be 'query-profile-type', not '" + root.getNodeName() + "'");
}
String idString=root.getAttribute("id");
- if (idString==null || idString.equals(""))
+ if (idString == null || idString.equals(""))
throw new IllegalArgumentException("'" + reader.getName() + "' has no 'id' attribute in the root element");
- ComponentId id=new ComponentId(idString);
+ ComponentId id = new ComponentId(idString);
validateFileNameToId(reader.getName(),id,"query profile type");
- QueryProfileType type=new QueryProfileType(id);
+ QueryProfileType type = new QueryProfileType(id);
type.setMatchAsPath(XML.getChild(root,"match") != null);
type.setStrict(XML.getChild(root,"strict") != null);
registry.register(type);
@@ -124,32 +120,33 @@ public class QueryProfileXMLReader {
}
public List<Element> createQueryProfiles(List<NamedReader> queryProfileReaders, QueryProfileRegistry registry) {
- List<Element> queryProfileElements=new ArrayList<>(queryProfileReaders.size());
+ List<Element> queryProfileElements = new ArrayList<>(queryProfileReaders.size());
for (NamedReader reader : queryProfileReaders) {
- Element root=XML.getDocument(reader).getDocumentElement();
+ Element root = XML.getDocument(reader).getDocumentElement();
if ( ! root.getNodeName().equals("query-profile")) {
- logger.info("Ignoring '" + reader.getName() +
- "': Expected XML root element 'query-profile' but was '" + root.getNodeName() + "'");
- continue;
+ throw new IllegalArgumentException("Root tag in '" + reader.getName() +
+ "' must be 'query-profile', not '" + root.getNodeName() + "'");
}
- String idString=root.getAttribute("id");
- if (idString==null || idString.equals(""))
- throw new IllegalArgumentException("Query profile '" + reader.getName() + "' has no 'id' attribute in the root element");
- ComponentId id=new ComponentId(idString);
- validateFileNameToId(reader.getName(),id,"query profile");
-
- QueryProfile queryProfile=new QueryProfile(id);
- String typeId=root.getAttribute("type");
- if (typeId!=null && ! typeId.equals("")) {
- QueryProfileType type=registry.getType(typeId);
- if (type==null)
- throw new IllegalArgumentException("Query profile '" + reader.getName() + "': Type id '" + typeId + "' can not be resolved");
+ String idString = root.getAttribute("id");
+ if (idString == null || idString.equals(""))
+ throw new IllegalArgumentException("Query profile '" + reader.getName() +
+ "' has no 'id' attribute in the root element");
+ ComponentId id = new ComponentId(idString);
+ validateFileNameToId(reader.getName(), id, "query profile");
+
+ QueryProfile queryProfile = new QueryProfile(id);
+ String typeId = root.getAttribute("type");
+ if (typeId != null && ! typeId.equals("")) {
+ QueryProfileType type = registry.getType(typeId);
+ if (type == null)
+ throw new IllegalArgumentException("Query profile '" + reader.getName() +
+ "': Type id '" + typeId + "' can not be resolved");
queryProfile.setType(type);
}
- Element dimensions=XML.getChild(root,"dimensions");
- if (dimensions!=null)
+ Element dimensions = XML.getChild(root,"dimensions");
+ if (dimensions != null)
queryProfile.setDimensions(toArray(XML.getValue(dimensions)));
registry.register(queryProfile);
@@ -159,66 +156,72 @@ public class QueryProfileXMLReader {
}
/** Throws an exception if the name is not corresponding to the id */
- private void validateFileNameToId(final String actualName,ComponentId id,String artifactName) {
- String expectedCanonicalFileName=id.toFileName();
- String expectedAlternativeFileName=id.stringValue().replace(":","-").replace("/","_"); // legacy
- String fileName=new File(actualName).getName();
- fileName=stripXmlEnding(fileName);
- String canonicalFileName=ComponentId.fromFileName(fileName).toFileName();
+ private void validateFileNameToId(String actualName, ComponentId id, String artifactName) {
+ String expectedCanonicalFileName = id.toFileName();
+ String expectedAlternativeFileName = id.stringValue().replace(":", "-").replace("/", "_"); // legacy
+ String fileName = new File(actualName).getName();
+ fileName = stripXmlEnding(fileName);
+ String canonicalFileName = ComponentId.fromFileName(fileName).toFileName();
if ( ! canonicalFileName.equals(expectedCanonicalFileName) && ! canonicalFileName.equals(expectedAlternativeFileName))
throw new IllegalArgumentException("The file name of " + artifactName + " '" + id +
- "' must be '" + expectedCanonicalFileName + ".xml' but was '" + actualName + "'");
+ "' must be '" + expectedCanonicalFileName + ".xml' but was '" +
+ actualName + "'");
}
private String stripXmlEnding(String fileName) {
- if (!fileName.endsWith(".xml"))
+ if ( ! fileName.endsWith(".xml"))
throw new IllegalArgumentException("'" + fileName + "' should have a .xml ending");
else
return fileName.substring(0,fileName.length()-4);
}
private String[] toArray(String csv) {
- String[] array=csv.split(",");
- for (int i=0; i<array.length; i++)
- array[i]=array[i].trim();
+ String[] array = csv.split(",");
+ for (int i = 0; i < array.length; i++)
+ array[i] = array[i].trim();
return array;
}
public void fillQueryProfileTypes(List<Element> queryProfileTypeElements, QueryProfileTypeRegistry registry) {
for (Element element : queryProfileTypeElements) {
- QueryProfileType type=registry.getComponent(new ComponentSpecification(element.getAttribute("id")).toId());
+ QueryProfileType type = registry.getComponent(new ComponentSpecification(element.getAttribute("id")).toId());
try {
- readInheritedTypes(element,type,registry);
- readFieldDefinitions(element,type,registry);
+ readInheritedTypes(element, type, registry);
+ readFieldDefinitions(element, type, registry);
}
catch (RuntimeException e) {
- throw new IllegalArgumentException("Error reading " + type,e);
+ throw new IllegalArgumentException("Error reading " + type, e);
}
}
}
- private void readInheritedTypes(Element element,QueryProfileType type,QueryProfileTypeRegistry registry) {
- String inheritedString=element.getAttribute("inherits");
- if (inheritedString==null || inheritedString.equals("")) return;
+ private void readInheritedTypes(Element element,QueryProfileType type, QueryProfileTypeRegistry registry) {
+ String inheritedString = element.getAttribute("inherits");
+ if (inheritedString == null || inheritedString.equals("")) return;
for (String inheritedId : inheritedString.split(" ")) {
- inheritedId=inheritedId.trim();
+ inheritedId = inheritedId.trim();
if (inheritedId.equals("")) continue;
- QueryProfileType inheritedType=registry.getComponent(inheritedId);
- if (inheritedType==null) throw new IllegalArgumentException("Could not resolve inherited query profile type '" + inheritedId);
+ QueryProfileType inheritedType = registry.getComponent(inheritedId);
+ if (inheritedType == null)
+ throw new IllegalArgumentException("Could not resolve inherited query profile type '" + inheritedId);
type.inherited().add(inheritedType);
}
}
- private void readFieldDefinitions(Element element,QueryProfileType type,QueryProfileTypeRegistry registry) {
+ private void readFieldDefinitions(Element element, QueryProfileType type, QueryProfileTypeRegistry registry) {
for (Element field : XML.getChildren(element,"field")) {
- String name=field.getAttribute("name");
- if (name==null || name.equals("")) throw new IllegalArgumentException("A field has no 'name' attribute");
+ String name = field.getAttribute("name");
+ if (name == null || name.equals("")) throw new IllegalArgumentException("A field has no 'name' attribute");
try {
- String fieldTypeName=field.getAttribute("type");
- if (fieldTypeName==null) throw new IllegalArgumentException("Field '" + field + "' has no 'type' attribute");
+ String fieldTypeName = field.getAttribute("type");
+ if (fieldTypeName == null) throw new IllegalArgumentException("Field '" + field + "' has no 'type' attribute");
FieldType fieldType=FieldType.fromString(fieldTypeName,registry);
- type.addField(new FieldDescription(name,fieldType,field.getAttribute("alias"),
- getBooleanAttribute("mandatory",false,field),getBooleanAttribute("overridable",true,field)), registry);
+ type.addField(new FieldDescription(name,
+ fieldType,
+ field.getAttribute("alias"),
+ getBooleanAttribute("mandatory", false, field),
+ getBooleanAttribute("overridable", true, field)),
+ registry);
}
catch(RuntimeException e) {
throw new IllegalArgumentException("Invalid field '" + name + "'",e);
@@ -229,46 +232,51 @@ public class QueryProfileXMLReader {
public void fillQueryProfiles(List<Element> queryProfileElements, QueryProfileRegistry registry) {
for (Element element : queryProfileElements) {
// Lookup by exact id
- QueryProfile profile=registry.getComponent(new ComponentSpecification(element.getAttribute("id")).toId());
+ QueryProfile profile = registry.getComponent(new ComponentSpecification(element.getAttribute("id")).toId());
try {
- readInherited(element,profile,registry,null,profile.toString());
- readFields(element,profile,registry,null,profile.toString());
- readVariants(element,profile,registry);
+ readInherited(element, profile, registry,null, profile.toString());
+ readFields(element, profile, registry,null, profile.toString());
+ readVariants(element, profile, registry);
}
catch (RuntimeException e) {
- throw new IllegalArgumentException("Error reading " + profile,e);
+ throw new IllegalArgumentException("Error reading " + profile, e);
}
}
}
- private void readInherited(Element element,QueryProfile profile,QueryProfileRegistry registry,DimensionValues dimensionValues,String sourceDescription) {
- String inheritedString=element.getAttribute("inherits");
- if (inheritedString==null || inheritedString.equals("")) return;
+ private void readInherited(Element element, QueryProfile profile, QueryProfileRegistry registry,
+ DimensionValues dimensionValues, String sourceDescription) {
+ String inheritedString = element.getAttribute("inherits");
+ if (inheritedString == null || inheritedString.equals("")) return;
for (String inheritedId : inheritedString.split(" ")) {
- inheritedId=inheritedId.trim();
+ inheritedId = inheritedId.trim();
if (inheritedId.equals("")) continue;
- QueryProfile inheritedProfile=registry.getComponent(inheritedId);
- if (inheritedProfile==null) throw new IllegalArgumentException("Could not resolve inherited query profile '" + inheritedId + "' in " + sourceDescription);
+ QueryProfile inheritedProfile = registry.getComponent(inheritedId);
+ if (inheritedProfile == null)
+ throw new IllegalArgumentException("Could not resolve inherited query profile '" +
+ inheritedId + "' in " + sourceDescription);
profile.addInherited(inheritedProfile,dimensionValues);
}
}
- private void readFields(Element element,QueryProfile profile,QueryProfileRegistry registry,DimensionValues dimensionValues,String sourceDescription) {
- List<KeyValue> references=new ArrayList<>();
- List<KeyValue> properties=new ArrayList<>();
+ private void readFields(Element element,QueryProfile profile, QueryProfileRegistry registry,
+ DimensionValues dimensionValues, String sourceDescription) {
+ List<KeyValue> references = new ArrayList<>();
+ List<KeyValue> properties = new ArrayList<>();
for (Element field : XML.getChildren(element,"field")) {
- String name=field.getAttribute("name");
- if (name==null || name.equals("")) throw new IllegalArgumentException("A field in " + sourceDescription + " has no 'name' attribute");
+ String name = field.getAttribute("name");
+ if (name == null || name.equals(""))
+ throw new IllegalArgumentException("A field in " + sourceDescription + " has no 'name' attribute");
try {
- Boolean overridable=getBooleanAttribute("overridable",null,field);
- if (overridable!=null)
- profile.setOverridable(name,overridable,null);
+ Boolean overridable = getBooleanAttribute("overridable",null,field);
+ if (overridable != null)
+ profile.setOverridable(name, overridable, null);
- Object fieldValue=readFieldValue(field,name,sourceDescription,registry);
+ Object fieldValue = readFieldValue(field, name, sourceDescription, registry);
if (fieldValue instanceof QueryProfile)
- references.add(new KeyValue(name,fieldValue));
+ references.add(new KeyValue(name, fieldValue));
else
- properties.add(new KeyValue(name,fieldValue));
+ properties.add(new KeyValue(name, fieldValue));
}
catch (IllegalArgumentException e) {
throw new IllegalArgumentException("Invalid field '" + name + "' in " + sourceDescription,e);
@@ -276,18 +284,18 @@ public class QueryProfileXMLReader {
}
// Must set references before properties
for (KeyValue keyValue : references)
- profile.set(keyValue.getKey() ,keyValue.getValue(), dimensionValues, registry);
+ profile.set(keyValue.getKey(), keyValue.getValue(), dimensionValues, registry);
for (KeyValue keyValue : properties)
profile.set(keyValue.getKey(), keyValue.getValue(), dimensionValues, registry);
}
- private Object readFieldValue(Element field,String name,String targetDescription,QueryProfileRegistry registry) {
- Element ref=XML.getChild(field,"ref");
- if (ref!=null) {
- String referencedName=XML.getValue(ref);
- QueryProfile referenced=registry.getComponent(referencedName);
- if (referenced==null)
+ private Object readFieldValue(Element field, String name, String targetDescription, QueryProfileRegistry registry) {
+ Element ref = XML.getChild(field,"ref");
+ if (ref != null) {
+ String referencedName = XML.getValue(ref);
+ QueryProfile referenced = registry.getComponent(referencedName);
+ if (referenced == null)
throw new IllegalArgumentException("Could not find query profile '" + referencedName + "' referenced as '" +
name + "' in " + targetDescription);
return referenced;
@@ -297,40 +305,41 @@ public class QueryProfileXMLReader {
}
}
- private void readVariants(Element element,QueryProfile profile,QueryProfileRegistry registry) {
+ private void readVariants(Element element, QueryProfile profile, QueryProfileRegistry registry) {
for (Element queryProfileVariantElement : XML.getChildren(element,"query-profile")) { // A "virtual" query profile contained inside another
- List<String> dimensions=profile.getDimensions();
- if (dimensions==null)
+ List<String> dimensions = profile.getDimensions();
+ if (dimensions == null)
throw new IllegalArgumentException("Cannot create a query profile variant in " + profile +
", as it has not declared any variable dimensions");
- String dimensionString=queryProfileVariantElement.getAttribute("for");
- String[] dimensionValueArray=makeStarsNull(toArray(dimensionString));
+ String dimensionString = queryProfileVariantElement.getAttribute("for");
+ String[] dimensionValueArray = makeStarsNull(toArray(dimensionString));
if (dimensions.size()<dimensionValueArray.length)
throw new IllegalArgumentException("Cannot create a query profile variant for '" + dimensionString +
"' as only " + dimensions.size() + " dimensions has been defined");
- DimensionValues dimensionValues=DimensionValues.createFrom(dimensionValueArray);
+ DimensionValues dimensionValues = DimensionValues.createFrom(dimensionValueArray);
- String description="variant '" + dimensionString + "' in " + profile.toString();
- readInherited(queryProfileVariantElement,profile,registry,dimensionValues,description);
- readFields(queryProfileVariantElement,profile,registry,dimensionValues,description);
+ String description = "variant '" + dimensionString + "' in " + profile.toString();
+ readInherited(queryProfileVariantElement, profile, registry, dimensionValues, description);
+ readFields(queryProfileVariantElement, profile, registry, dimensionValues, description);
}
}
private String[] makeStarsNull(String[] strings) {
- for (int i=0; i<strings.length; i++)
+ for (int i = 0; i < strings.length; i++)
if (strings[i].equals("*"))
- strings[i]=null;
+ strings[i] = null;
return strings;
}
/**
- * Returns true if the string is "true".<br>
- * Returns false if the string is "false".<br>
- * Returns <code>default</code> if the string is null or empty (this parameter may be null)<br>
+ * Returns true if the string is "true".
+ * Returns false if the string is "false".
+ * Returns <code>default</code> if the string is null or empty (this parameter may be null).
+ *
* @throws IllegalArgumentException if the string has any other value
*/
private Boolean asBoolean(String s,Boolean defaultValue) {
- if (s==null) return defaultValue;
+ if (s == null) return defaultValue;
if (s.isEmpty()) return defaultValue;
if ("true".equals(s)) return true;
if ("false".equals(s)) return false;
@@ -338,12 +347,12 @@ public class QueryProfileXMLReader {
}
/** Returns the given attribute as a boolean, using the semantics of {@link #asBoolean} */
- private Boolean getBooleanAttribute(String attributeName,Boolean defaultValue,Element from) {
+ private Boolean getBooleanAttribute(String attributeName, Boolean defaultValue, Element from) {
try {
- return asBoolean(from.getAttribute(attributeName),defaultValue);
+ return asBoolean(from.getAttribute(attributeName), defaultValue);
}
catch (IllegalArgumentException e) {
- throw new IllegalArgumentException("Attribute '" + attributeName,e);
+ throw new IllegalArgumentException("Attribute '" + attributeName, e);
}
}
@@ -352,9 +361,9 @@ public class QueryProfileXMLReader {
private String key;
private Object value;
- public KeyValue(String key,Object value) {
- this.key=key;
- this.value=value;
+ public KeyValue(String key, Object value) {
+ this.key = key;
+ this.value = value;
}
public String getKey() { return key; }