diff options
author | Jon Bratseth <bratseth@yahoo-inc.com> | 2016-06-15 23:09:44 +0200 |
---|---|---|
committer | Jon Bratseth <bratseth@yahoo-inc.com> | 2016-06-15 23:09:44 +0200 |
commit | 72231250ed81e10d66bfe70701e64fa5fe50f712 (patch) | |
tree | 2728bba1131a6f6e5bdf95afec7d7ff9358dac50 /config-model/src/main/java/com/yahoo/vespa/documentmodel |
Publish
Diffstat (limited to 'config-model/src/main/java/com/yahoo/vespa/documentmodel')
8 files changed, 844 insertions, 0 deletions
diff --git a/config-model/src/main/java/com/yahoo/vespa/documentmodel/DocumentModel.java b/config-model/src/main/java/com/yahoo/vespa/documentmodel/DocumentModel.java new file mode 100644 index 00000000000..6c8206d30f2 --- /dev/null +++ b/config-model/src/main/java/com/yahoo/vespa/documentmodel/DocumentModel.java @@ -0,0 +1,31 @@ +// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.vespa.documentmodel; + +import com.yahoo.documentmodel.DocumentTypeRepo; + +/** + * DocumentModel represents everything derived from a set of search definitions. + * It contains a document manager managing all defined document types. + * It contains a search manager managing all specified search definitions. + * It contains a storage manager managing all specified storage definitions. + * + * @author balder + * @since 2010-02-19 + */ +public class DocumentModel { + private DocumentTypeRepo documentMan = new DocumentTypeRepo(); + private SearchManager searchMan = new SearchManager(); + + /** + * + * @return Returns the DocumentManager + */ + public DocumentTypeRepo getDocumentManager() { return documentMan; } + + /** + * + * @return Returns the SearchManager + */ + public SearchManager getSearchManager() { return searchMan; } + +} diff --git a/config-model/src/main/java/com/yahoo/vespa/documentmodel/DocumentSummary.java b/config-model/src/main/java/com/yahoo/vespa/documentmodel/DocumentSummary.java new file mode 100644 index 00000000000..42fa7b04cf6 --- /dev/null +++ b/config-model/src/main/java/com/yahoo/vespa/documentmodel/DocumentSummary.java @@ -0,0 +1,79 @@ +// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.vespa.documentmodel; + +import com.yahoo.document.Field; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; + +/** + * A document summary definition - a list of summary fields. + * + * @author <a href="mailto:bratseth@yahoo-inc.com">Jon S Bratseth</a> + */ +public class DocumentSummary extends FieldView { + + + /** + * Will create a DocumentSummary with the given name. + * @param name The name to use for this summary. + */ + public DocumentSummary(String name) { + super(name); + } + + /** + * The model is constrained to ensure that summary fields of the same name + * in different classes have the same summary transform, because this is + * what is supported by the backend currently. + * @param summaryField The summaryfield to add + */ + public void add(SummaryField summaryField) { + summaryField.addDestination(getName()); + super.add(summaryField); + } + + public SummaryField getSummaryField(String name) { + return (SummaryField) get(name); + } + + public Collection<SummaryField> getSummaryFields() { + ArrayList<SummaryField> fields = new ArrayList<>(getFields().size()); + for(Field f : getFields()) { + fields.add((SummaryField) f); + } + return fields; + } + + /** + * Removes implicit fields which shouldn't be included. + * This is implicitly added fields which are sources for + * other fields. We then assume they are not intended to be added + * implicitly in additon. + * This should be called when this summary is complete. + */ + public void purgeImplicits() { + List<SummaryField> falseImplicits = new ArrayList<>(); + for (SummaryField summaryField : getSummaryFields() ) { + if (summaryField.isImplicit()) continue; + for (Iterator<SummaryField.Source> j = summaryField.sourceIterator(); j.hasNext(); ) { + String sourceName = j.next().getName(); + if (sourceName.equals(summaryField.getName())) continue; + SummaryField sourceField=getSummaryField(sourceName); + if (sourceField==null) continue; + if (!sourceField.isImplicit()) continue; + falseImplicits.add(sourceField); + } + } + for (SummaryField field : falseImplicits) { + remove(field.getName()); + } + } + + public String toString() { + return "document summary '" + getName() + "'"; + } + +} diff --git a/config-model/src/main/java/com/yahoo/vespa/documentmodel/FieldView.java b/config-model/src/main/java/com/yahoo/vespa/documentmodel/FieldView.java new file mode 100644 index 00000000000..dfb44aef917 --- /dev/null +++ b/config-model/src/main/java/com/yahoo/vespa/documentmodel/FieldView.java @@ -0,0 +1,61 @@ +// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.vespa.documentmodel; + +import com.yahoo.document.Field; + +import java.io.Serializable; +import java.util.Collection; +import java.util.LinkedHashMap; +import java.util.Map; + +/** + * @author balder + * @since 2010-02-19 + */ +public class FieldView implements Serializable { + private String name; + private Map<String, Field> fields = new LinkedHashMap<>(); + + /** + * Creates a view with a name + * @param name Name of the view. + */ + public FieldView(String name) { + this.name = name; + } + public String getName() { return name; } + public Collection<Field> getFields() { return fields.values(); } + public Field get(String name) { return fields.get(name); } + public void remove(String name) { fields.remove(name); } + + /** + * This method will add a field to a view. All fields must come from the same document type. Not enforced here. + * @param field The field to add. + * @return Itself for chaining purposes. + */ + public FieldView add(Field field) { + if (fields.containsKey(field.getName())) { + if ( ! fields.get(field.getName()).equals(field)) { + throw new IllegalArgumentException( + "View '" + name + "' already contains a field with name '" + + field.getName() + "' and definition : " + + fields.get(field.getName()).toString() + ". Your is : " + field.toString()); + } + } else { + fields.put(field.getName(), field); + } + return this; + } + + /** + * This method will join the two views. + * @param view The view to be joined in to this. + * @return Itself for chaining. + */ + public FieldView add(FieldView view) { + for(Field field : view.getFields()) { + add(field); + } + return this; + } +} diff --git a/config-model/src/main/java/com/yahoo/vespa/documentmodel/SearchDef.java b/config-model/src/main/java/com/yahoo/vespa/documentmodel/SearchDef.java new file mode 100644 index 00000000000..07b7c973841 --- /dev/null +++ b/config-model/src/main/java/com/yahoo/vespa/documentmodel/SearchDef.java @@ -0,0 +1,126 @@ +// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.vespa.documentmodel; + +import com.yahoo.document.DataType; +import com.yahoo.document.DocumentType; +import com.yahoo.document.DocumentTypeManager; + +import java.util.HashMap; +import java.util.Map; +import java.util.logging.Logger; + +/** + * @author balder + * @since 2010-02-19 + */ +public class SearchDef { + private final static Logger log = Logger.getLogger(SearchDef.class.getName()); + /// Name of the searchdefinition + private String name; + /// These are the real backing documenttypes + private DocumentTypeManager sources = new DocumentTypeManager(); + /// Map of all search fields + private Map<String, SearchField> fields = new HashMap<>(); + /// Map of all views that can be searched. + private Map<String, FieldView> views = new HashMap<>(); + /// Map of all aliases <alias, realname> + private Map<String, String> aliases = new HashMap<>(); + + /** + * Will create a SearchDef with the given name + * @param name The name of the searchdefinition + */ + public SearchDef(String name) { + this.name = name; + } + + /** + * This will provide you with the name of the searchdefinition. + * @return The name of the searchdefinition. + */ + public String getName() { return name; } + + public Map<String, SearchField> getFields() { return fields; } + public Map<String, FieldView> getViews() { return views; } + + /** + * Adds a document that can be mapped to this search. + * @param source A document that can be mapped to this search. + * @return Itself for chaining. + */ + public SearchDef add(DataType source) { + sources.register(source); + return this; + } + + private void noShadowing(String name) { + noFieldShadowing(name); + noViewShadowing(name); + } + + private void noFieldShadowing(String name) { + if (fields.containsKey(name)) { + throw new IllegalArgumentException("Searchdef '" + getName() + "' already contains the fields '" + fields.toString() + + "'. You are trying to add '" + name + "'. Shadowing is not supported"); + } + } + + private void noViewShadowing(String name) { + if (views.containsKey(name)) { + throw new IllegalArgumentException("Searchdef '" + getName() + "' already contains a view with name '" + + name + "'. Shadowing is not supported."); + } + } + + /** + * Adds a search field to the definition. + * @param field The field to add. + * @return Itself for chaining. + */ + public SearchDef add(SearchField field) { + try { + noFieldShadowing(field.getName()); + fields.put(field.getName(), field); + } catch (IllegalArgumentException e) { + if (views.containsKey(field.getName())) { + throw e; + } + } + return this; + } + + public SearchDef addAlias(String alias, String aliased) { + noShadowing(alias); + if (!fields.containsKey(aliased) && !views.containsKey(aliased)) { + if (aliased.contains(".")) { + // TODO Here we should nest ourself down to something that really exists. + log.warning("Aliased item '" + aliased + "' not verifiable. Allowing it to be aliased to '" + alias + " for now. Validation will come when URL/Position is structified."); + } else { + throw new IllegalArgumentException("Searchdef '" + getName() + "' has nothing named '" + aliased + "'to alias to '" + alias + "'."); + } + } + String oldAliased = aliases.get(alias); + if ((oldAliased != null)) { + if (oldAliased.equals(aliased)) { + throw new IllegalArgumentException("Searchdef '" + getName() + "' already has the alias '" + alias + + "' to '" + aliased + ". Why do you want to add it again."); + + } else { + throw new IllegalArgumentException("Searchdef '" + getName() + "' already has the alias '" + alias + + "' to '" + oldAliased + ". Cannot change it to alias '" + aliased + "'."); + } + } else { + aliases.put(alias, aliased); + } + return this; + } + + public SearchDef add(FieldView view) { + noViewShadowing(view.getName()); + if (views.containsKey(view.getName())) { + views.get(view.getName()).add(view); + } + views.put(view.getName(), view); + return this; + } +} diff --git a/config-model/src/main/java/com/yahoo/vespa/documentmodel/SearchField.java b/config-model/src/main/java/com/yahoo/vespa/documentmodel/SearchField.java new file mode 100644 index 00000000000..2db81861955 --- /dev/null +++ b/config-model/src/main/java/com/yahoo/vespa/documentmodel/SearchField.java @@ -0,0 +1,71 @@ +// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.vespa.documentmodel; + +import com.yahoo.document.DataType; +import com.yahoo.document.Field; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author balder + * @since 2010-02-19 + */ +public class SearchField extends Field { + /// Indicate if field shall be stored in memory for attribute usage. + private boolean attribute = false; + /// Indicate if the field is Vespa indexed. + private boolean indexed = false; + /// Indication to backend on how much optimization should be done. + + /** + * This is a representation of features to generate for this field. + * It can be both optimize hints, and real functional hints. + */ + public enum Feature { + WEIGHT_IN_ATTRIBUTE_POSTINGS("WeightInAttributePosting"), // Hint to put the weight in postings for attribute. + WORDPOS_IN_POSTINGS("WordPosInPosting"), // Default for generating posocc + FILTER_ONLY("FilterOnly"); // Might only generate bitvector + private String name; + Feature(String name) { this.name = name;} + public String getName() { return name; } + } + private List<Feature> featureList = new ArrayList<>(); + + public SearchField(Field field, boolean indexed, boolean attribute) { + this(field, indexed, attribute, null); + } + public SearchField(Field field, boolean indexed, boolean attribute, List<Feature> features) { + super(field.getName(), field); + this.attribute = attribute; + this.indexed = indexed; + if (features != null) { + featureList.addAll(features); + } + validate(); + } + + @SuppressWarnings({ "deprecation" }) + private void validate() { + if (attribute || !indexed) { + return; + } + DataType fieldType = getDataType(); + DataType primiType = fieldType.getPrimitiveType(); + if (DataType.STRING.equals(primiType) || DataType.URI.equals(primiType)) { + return; + } + throw new IllegalStateException("Expected type " + DataType.STRING.getName() + " for indexed field '" + + getName() + "', got " + fieldType.getName() + "."); + } + + public SearchField setIndexed() { indexed = true; validate(); return this; } + public SearchField setAttribute() { attribute = true; validate(); return this; } + public boolean isAttribute() { return attribute; } + /** + * True if field is Vespa indexed + * @return true if indexed + */ + public boolean isIndexed() { return indexed; } + public SearchField addFeature(Feature feature) { featureList.add(feature); validate(); return this; } +} diff --git a/config-model/src/main/java/com/yahoo/vespa/documentmodel/SearchManager.java b/config-model/src/main/java/com/yahoo/vespa/documentmodel/SearchManager.java new file mode 100644 index 00000000000..29a960f7e7b --- /dev/null +++ b/config-model/src/main/java/com/yahoo/vespa/documentmodel/SearchManager.java @@ -0,0 +1,27 @@ +// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.vespa.documentmodel; + +import java.util.TreeMap; + +/** + * @author balder + * @since 2010-02-19 + */ +public class SearchManager { + /// This is the list of all known search definitions + private TreeMap<String, SearchDef> defs = new TreeMap<>(); + + /** + * This will add a searchdefinition or throw an IllegalArgumentException if the name is already used + * @param def The searchdef to add + * @return itself for chaining purposes. + */ + public SearchManager add(SearchDef def) { + if (defs.containsKey(def.getName())) { + throw new IllegalArgumentException("There already exist a searchdefinition with this content:\n" + + defs.get(def.getName()).toString() + "\n No room for : " + def.toString()); + } + defs.put(def.getName(), def); + return this; + } +} diff --git a/config-model/src/main/java/com/yahoo/vespa/documentmodel/SummaryField.java b/config-model/src/main/java/com/yahoo/vespa/documentmodel/SummaryField.java new file mode 100644 index 00000000000..f6db82785b0 --- /dev/null +++ b/config-model/src/main/java/com/yahoo/vespa/documentmodel/SummaryField.java @@ -0,0 +1,350 @@ +// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.vespa.documentmodel; + +import com.yahoo.document.DataType; +import com.yahoo.document.Field; +import com.yahoo.searchdefinition.document.TypedKey; + +import java.io.Serializable; +import java.util.*; + +import static com.yahoo.text.Lowercase.toLowerCase; + +/** + * A summary field + * + * @author bratseth + */ +public class SummaryField extends Field implements Cloneable, TypedKey { + + /** + * This class represents a source (field name) and the type of the source (only used for smart summary) + */ + public static class Source implements Serializable { + public static enum Type { + CONTEXTUAL("contextual"), + TITLE("title"), + STATIC("static"), + URL("url"); + private final String name; + Type(String name) { + this.name = name; + } + public String getName() { return name; } + } + private String name; + private Type type; + private boolean override = false; + public Source(String name) { + this.name = name; + this.type = Type.CONTEXTUAL; + } + public Source(String name, Type type) { + this.name = name; + this.type = type; + } + public String getName() { return name; } + public Type getType() { return type; } + public void setOverride(boolean override) { this.override = override; } + public boolean getOverride() { return override; } + public int hashCode() { + return name.hashCode() + type.getName().hashCode() + Boolean.valueOf(override).hashCode(); + } + public boolean equals(Object obj) { + if (!(obj instanceof Source)) { + return false; + } + Source other = (Source)obj; + return name.equals(other.name) && + type.getName().equals(other.type.getName()) && + override == other.override; + } + public String toString() { + return name; + } + } + + /** A name-value property (used for smart summary) */ + public static class Property implements Serializable { + private String name; + private String value; + public Property(String name, String value) { + this.name = name; + this.value = value; + } + public String getName() { return name; } + public String getValue() { return value; } + public @Override int hashCode() { + return name.hashCode() + 17*value.hashCode(); + } + public @Override boolean equals(Object obj) { + if (!(obj instanceof Property)) { + return false; + } + Property other = (Property)obj; + return name.equals(other.name) && value.equals(other.value); + } + } + + /** The transform to perform on the stored source */ + private SummaryTransform transform=SummaryTransform.NONE; + + /** The command used per field in vsmsummary */ + private VsmCommand vsmCommand = VsmCommand.NONE; + + /** + * The data sources for this output summary field, in prioritized order + * (use only second source if first yields no result after transformation + * and so on). If no sources are given explicitly, the field of the same + * name as this summary field is used + */ + private Set<Source> sources = new java.util.LinkedHashSet<>(); + + private Set<String> destinations=new java.util.LinkedHashSet<>(); + + /** True if this field was defined implicitly */ + private boolean implicit=false; + + /** The list of properties for this summary field */ + private List<Property> properties = new ArrayList<>(); + + /** Creates a summary field with NONE as transform */ + public SummaryField(String name, DataType type) { + this(name,type,SummaryTransform.NONE); + } + + /** Creates a summary field with NONE as transform */ + public SummaryField(Field field) { + this(field,SummaryTransform.NONE); + } + + + public SummaryField(Field field,SummaryTransform transform) { + this(field.getName(), field.getDataType(), transform); + } + + public SummaryField(String name,DataType type,SummaryTransform transform) { + super(name, type); + this.transform=transform; + } + + public void setImplicit(boolean implicit) { this.implicit=implicit; } + + @Override // override to make public + public void setDataType(DataType type) { + super.setDataType(type); + } + + public boolean isImplicit() { return implicit; } + + public void setTransform(SummaryTransform transform) { + this.transform=transform; + if (SummaryTransform.DYNAMICTEASER.equals(transform) || SummaryTransform.BOLDED.equals(transform)) { + // This is the kind of logic we want to have in processing, + // but can't because of deriveDocuments mode, which doesn't run + // processing. + setVsmCommand(VsmCommand.FLATTENJUNIPER); + } + } + + public SummaryTransform getTransform() { return transform; } + + /** Returns the first source field of this, or null if the source field is not present */ + public String getSourceField() { + String sourceName=getName(); + if (sources.size()>0) + sourceName=sources.iterator().next().getName(); + return sourceName; + } + + public void addSource(String name) { + sources.add(new Source(name)); + } + + public void addSource(Source source) { + sources.add(source); + } + + public Iterator<Source> sourceIterator() { + return sources.iterator(); + } + + public int getSourceCount() { + return sources.size(); + } + + /** Returns a modifiable set of the sources of this */ + public Set<Source> getSources() { return sources; } + + /** Returns the first source name of this, or the field name if no source has been set */ + public String getSingleSource() { + if (sources.size()==0) return getName(); + return sources.iterator().next().getName(); + } + + public void addDestination(String name) { + destinations.add(name); + } + + public final void addDestinations(Iterable<String> names) { + for (String name : names) { + addDestination(name); + } + } + + /** Returns an modifiable view of the destination set owned by this */ + public Set<String> getDestinations() { + return destinations; + } + + private String toString(Collection<?> collection) { + StringBuffer buffer=new StringBuffer(); + for (Iterator<?> i=collection.iterator(); i.hasNext(); ) { + buffer.append(i.next().toString()); + if (i.hasNext()) + buffer.append(", "); + } + return buffer.toString(); + } + + /** + * Returns a summary field which merges the settings in the given field + * into this field + * + * @param merge the field to merge with this, if null, the merged field is + * <code>this</code> field + * @throws RuntimeException if the two fields can not be merged + */ + public SummaryField mergeWith(SummaryField merge) { + if (merge==null) return this; + if (this.isImplicit()) return merge; + if (merge.isImplicit()) return this; + + if (!merge.getName().equals(getName())) + throw new IllegalArgumentException(merge + " conflicts with " + this + + ": different names"); + + if (!merge.getTransform().equals(getTransform())) + throw new IllegalArgumentException(merge + " conflicts with " + this + + ": different transforms"); + + if (!merge.getDataType().equals(getDataType())) + throw new IllegalArgumentException(merge + " conflicts with " + this + + ": different types"); + + if (!merge.isImplicit()) + setImplicit(false); + + if (isHeadOf(this.sourceIterator(),merge.sourceIterator())) { + // Ok + } + else if (isHeadOf(merge.sourceIterator(),this.sourceIterator())) { + sources=new LinkedHashSet<>(merge.sources); + } + else { + throw new IllegalArgumentException(merge + " conflicts with " + this + + ": on source list must be the start of the other"); + } + + destinations.addAll(merge.destinations); + + return this; + } + + public boolean hasSource(String name) { + for (Source s : sources) { + if (s.getName().equals(name)) { + return true; + } + } + return false; + } + + /** + * Returns true if the second list is the start of the first list + */ + private boolean isHeadOf(Iterator<?> full, Iterator<?> head) { + while (head.hasNext()) { + if (!full.hasNext()) return false; + + if (!full.next().equals(head.next())) return false; + } + return true; + } + + private String getDestinationString() + { + StringBuilder destinationString = new StringBuilder("destinations("); + for (String destination : destinations) { + destinationString.append(destination).append(" "); + } + destinationString.append(")"); + return destinationString.toString(); + } + + public String toString() { + return + "summary field '" + getName() + ' ' + getDestinationString() + + "' [type: '" + getDataType().getName() + + "' transform: '" + transform + + "', source: '" + toString(sources) + + "', to '" + toString(destinations) + "']"; + } + + /** returns a string which aids locating this field in the source search definition */ + public String toLocateString() { + return "'summary " + getName() + " type " + toLowerCase(getDataType().getName()) + "' in '" + getDestinationString() + "'"; + } + + public SummaryField clone() { + try { + SummaryField clone=(SummaryField)super.clone(); + if (this.sources!=null) + clone.sources=new LinkedHashSet<>(this.sources); + if (this.destinations!=null) + clone.destinations=new LinkedHashSet<>(destinations); + return clone; + } + catch (CloneNotSupportedException e) { + throw new RuntimeException("Programming error"); + } + } + + public VsmCommand getVsmCommand() { + return vsmCommand; + } + + public void setVsmCommand(VsmCommand vsmCommand) { + this.vsmCommand = vsmCommand; + } + + /** Adds a property to this summary field */ + public void addProperty(String name, String value) { + properties.add(new Property(name, value)); + } + + public List<Property> getProperties() { + return properties; + } + + /** + * The command used when using data from this SummaryField to generate StreamingSummary config (vsmsummary). + * Not used for ordinary Summary config. + * @author vegardh + * + */ + public enum VsmCommand { + NONE("NONE"), + FLATTENSPACE("FLATTENSPACE"), + FLATTENJUNIPER("FLATTENJUNIPER"); + + private String cmd=""; + private VsmCommand(String cmd) { + this.cmd=cmd; + } + @Override + public String toString() { + return cmd; + } + } +} diff --git a/config-model/src/main/java/com/yahoo/vespa/documentmodel/SummaryTransform.java b/config-model/src/main/java/com/yahoo/vespa/documentmodel/SummaryTransform.java new file mode 100644 index 00000000000..05092d50951 --- /dev/null +++ b/config-model/src/main/java/com/yahoo/vespa/documentmodel/SummaryTransform.java @@ -0,0 +1,99 @@ +// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.vespa.documentmodel; + +/** + * A value class representing a search time + * transformation on a summary field. + * + * @author bratseth + */ +public enum SummaryTransform { + + NONE("none"), + ATTRIBUTE("attribute"), + BOLDED("bolded"), + DISTANCE("distance"), + DYNAMICBOLDED("dynamicbolded"), + DYNAMICTEASER("dynamicteaser"), + POSITIONS("positions"), + RANKFEATURES("rankfeatures"), + SUMMARYFEATURES("summaryfeatures"), + TEXTEXTRACTOR("textextractor"), + GEOPOS("geopos"); + + private String name; + + private SummaryTransform(String name) { + this.name=name; + } + + public String getName() { + return name; + } + + /** Returns the bolded version of this transform if possible, throws if not */ + public SummaryTransform bold() { + switch (this) { + case NONE: + case BOLDED: + return BOLDED; + + case DYNAMICBOLDED: + case DYNAMICTEASER: + return DYNAMICBOLDED; + + default: + throw new IllegalArgumentException("Can not bold a '" + this + "' field."); + } + } + + /** Returns the unbolded version of this transform */ + public SummaryTransform unbold() { + switch (this) { + case NONE: + case BOLDED: + return NONE; + + case DYNAMICBOLDED: + return DYNAMICTEASER; + + default: + return this; + } + } + + /** Returns whether this value is bolded */ + public boolean isBolded() { + return this==BOLDED || this==DYNAMICBOLDED; + } + + /** Whether this is dynamically generated, both teasers and bolded fields are dynamic */ + public boolean isDynamic() { + return this==BOLDED || this==DYNAMICBOLDED || this==DYNAMICTEASER; + } + + /** Returns whether this is a teaser, not the complete field value */ + public boolean isTeaser() { + return this==DYNAMICBOLDED || this==DYNAMICTEASER; + } + + /** Returns whether this transform always gets its value by accessing memory only */ + public boolean isInMemory() { + switch (this) { + case ATTRIBUTE: + case DISTANCE: + case POSITIONS: + case GEOPOS: + case RANKFEATURES: + case SUMMARYFEATURES: + return true; + + default: + return false; + } + } + + public String toString() { + return name; + } +} |