summaryrefslogtreecommitdiffstats
path: root/container-search/src/main/java/com/yahoo/prelude
diff options
context:
space:
mode:
Diffstat (limited to 'container-search/src/main/java/com/yahoo/prelude')
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/Index.java16
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/IndexFacts.java83
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/IndexModel.java9
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/Pong.java2
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/SearchDefinition.java15
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/cluster/ClusterSearcher.java24
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/fastsearch/ClusterParams.java13
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/fastsearch/DocsumDefinition.java6
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/fastsearch/DocsumDefinitionSet.java19
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/fastsearch/DocsumField.java15
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/fastsearch/DocumentDatabase.java5
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/fastsearch/FastHit.java32
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/fastsearch/FeatureDataField.java18
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/fastsearch/StructDataField.java3
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/fastsearch/VespaBackEndSearcher.java4
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/fastsearch/XMLField.java6
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/hitfield/FieldIterator.java2
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/hitfield/HitField.java25
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/hitfield/JSONString.java1
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/hitfield/TokenFieldIterator.java2
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/logging/AccessLogEntry.java18
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/logging/package-info.java5
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/query/parser/AdvancedParser.java2
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/querytransform/IndexCombinatorSearcher.java361
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/searcher/BlendingSearcher.java22
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/searcher/DocumentSourceSearcher.java225
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/searcher/JuniperSearcher.java28
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/searcher/QuerySnapshotSearcher.java31
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/searcher/QueryValidatingSearcher.java38
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/semantics/SemanticSearcher.java3
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/statistics/StatisticsSearcher.java3
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/templates/Context.java116
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/templates/DefaultTemplateSet.java299
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/templates/FormattingOptions.java193
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/templates/GenericTemplateSet.java158
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/templates/HitContext.java147
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/templates/LogExceptionUserTemplateDelegator.java201
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/templates/MapContext.java38
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/templates/PageTemplateSet.java76
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/templates/SearchRendererAdaptor.java259
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/templates/Template.java36
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/templates/TemplateSet.java218
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/templates/TiledTemplateSet.java356
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/templates/UserTemplate.java312
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/templates/package-info.java7
45 files changed, 76 insertions, 3376 deletions
diff --git a/container-search/src/main/java/com/yahoo/prelude/Index.java b/container-search/src/main/java/com/yahoo/prelude/Index.java
index 109ecfd29f8..8433939090b 100644
--- a/container-search/src/main/java/com/yahoo/prelude/Index.java
+++ b/container-search/src/main/java/com/yahoo/prelude/Index.java
@@ -53,7 +53,6 @@ public class Index {
private boolean uriIndex = false;
private boolean hostIndex = false;
private StemMode stemMode = StemMode.NONE;
- private Attribute[] matchGroup = null;
private boolean isAttribute = false;
private boolean isDefaultPosition = false;
private boolean dynamicSummary=false;
@@ -165,8 +164,6 @@ public class Index {
setAttribute(true);
} else if (commandString.equals("default-position")) {
setDefaultPosition(true);
- } else if (commandString.startsWith("match-group ")) {
- setMatchGroup(commandString.substring(12).split(" "));
} else if (commandString.equals("plain-tokens")) {
setPlainTokens(true);
} else if (commandString.equals("multivalue")) {
@@ -269,19 +266,6 @@ public class Index {
return "(null)".equals(name);
}
- public Attribute[] getMatchGroup() { // TODO: Not in use on Vespa 6
- return matchGroup;
- }
-
- public void setMatchGroup(String[] attributes) {
- Attribute[] a = new Attribute[attributes.length];
-
- for (int i = 0; i < attributes.length; i++) {
- a[i] = new Attribute(attributes[i].trim());
- }
- this.matchGroup = a;
- }
-
public boolean isAttribute() {
return isAttribute;
}
diff --git a/container-search/src/main/java/com/yahoo/prelude/IndexFacts.java b/container-search/src/main/java/com/yahoo/prelude/IndexFacts.java
index 448d8e7855f..2fcd2466dd8 100644
--- a/container-search/src/main/java/com/yahoo/prelude/IndexFacts.java
+++ b/container-search/src/main/java/com/yahoo/prelude/IndexFacts.java
@@ -44,12 +44,8 @@ public class IndexFacts {
/**
* The name of the default search definition, which is the union of all
* known document types.
- *
- * @deprecated do not use
*/
- // TODO: Make this package private in Vespa 7
- @Deprecated // OK
- public static final String unionName = "unionOfAllKnown";
+ static final String unionName = "unionOfAllKnown";
/** A search definition which contains the union of all settings. */
@SuppressWarnings("deprecation")
@@ -106,31 +102,6 @@ public class IndexFacts {
return clusters != null ? clusters : Collections.<String>emptyList();
}
- /**
- * Public only for testing.
- *
- * @deprecated set at creation time
- */
- // TODO: Remove on Vespa 7
- @Deprecated // OK
- public void setClusters(Map<String, List<String>> clusters) {
- ensureNotFrozen();
- this.clusters = clusters;
- clusterByDocument = invert(clusters);
- }
-
- /**
- * @deprecated set indexes at creation time instead
- */
- // TODO: Remove on Vespa 7
- @Deprecated // OK
- public void setSearchDefinitions(Map<String, SearchDefinition> searchDefinitions,
- SearchDefinition unionSearchDefinition) {
- ensureNotFrozen();
- this.searchDefinitions = searchDefinitions;
- this.unionSearchDefinition = unionSearchDefinition;
- }
-
private boolean isInitialized() {
return searchDefinitions.size() > 0;
}
@@ -312,58 +283,6 @@ public class IndexFacts {
}
}
-
- /**
- * Add a string to be accepted as an index name when parsing a
- * query.
- *
- * For testing only.
- *
- * @param sdName name of search definition containing index, if null, modify default set
- * @param indexName name of index, actual or otherwise
- * @deprecated set indexes at creation time instead
- */
- // TODO: Remove on Vespa 7
- @Deprecated // OK
- public void addIndex(String sdName, String indexName) {
- ensureNotFrozen();
-
- SearchDefinition sd;
- if (sdName == null) {
- sd = unionSearchDefinition;
- } else if (searchDefinitions.containsKey(sdName)) {
- sd = searchDefinitions.get(sdName);
- } else {
- sd = new SearchDefinition(sdName);
- searchDefinitions.put(sdName, sd);
- }
- sd.getOrCreateIndex(indexName);
- unionSearchDefinition.getOrCreateIndex(indexName);
- }
-
- /**
- * Adds an index to the specified index, and the default index settings,
- * overriding any current settings for this index
- * @deprecated set indexes at creation time instead
- */
- // TODO: Remove on Vespa 7
- @Deprecated // OK
- public void addIndex(String sdName, Index index) {
- ensureNotFrozen();
-
- SearchDefinition sd;
- if (sdName == null) {
- sd = unionSearchDefinition;
- } else if (searchDefinitions.containsKey(sdName)) {
- sd = searchDefinitions.get(sdName);
- } else {
- sd = new SearchDefinition(sdName);
- searchDefinitions.put(sdName, sd);
- }
- sd.addIndex(index);
- unionSearchDefinition.addIndex(index);
- }
-
public String getDefaultPosition(String sdName) {
SearchDefinition sd;
if (sdName == null) {
diff --git a/container-search/src/main/java/com/yahoo/prelude/IndexModel.java b/container-search/src/main/java/com/yahoo/prelude/IndexModel.java
index d2950078868..dd2bd1ee2f1 100644
--- a/container-search/src/main/java/com/yahoo/prelude/IndexModel.java
+++ b/container-search/src/main/java/com/yahoo/prelude/IndexModel.java
@@ -39,8 +39,10 @@ public final class IndexModel {
/**
* Use IndexModel as a pure wrapper for the parameters given.
+ *
+ * @deprecated use the constructor without the third parameter
*/
- // TODO: Deprecate on Vespa 7 and remove on Vespa 8
+ @Deprecated // TODO: Remove Vespa 8
public IndexModel(Map<String, List<String>> masterClusters,
Map<String, SearchDefinition> searchDefinitions,
SearchDefinition unionSearchDefinition) {
@@ -90,7 +92,6 @@ public final class IndexModel {
IndexInfoConfig.Indexinfo.Command command = j.next();
sd.addCommand(command.indexname(),command.command());
}
- sd.fillMatchGroups();
searchDefinitions.put(info.name(), sd);
}
@@ -127,7 +128,6 @@ public final class IndexModel {
}
}
- union.fillMatchGroups();
return union;
}
@@ -135,7 +135,8 @@ public final class IndexModel {
public Map<String, SearchDefinition> getSearchDefinitions() { return searchDefinitions; }
- // TODO: Deprecate on Vespa 7 and make package scope on Vespa 8
+ /** @deprecated do not use */
+ @Deprecated // TODO: Remove on Vespa 8
public SearchDefinition getUnionSearchDefinition() { return unionSearchDefinition; }
}
diff --git a/container-search/src/main/java/com/yahoo/prelude/Pong.java b/container-search/src/main/java/com/yahoo/prelude/Pong.java
index ba3ff2eda00..cef64c293af 100644
--- a/container-search/src/main/java/com/yahoo/prelude/Pong.java
+++ b/container-search/src/main/java/com/yahoo/prelude/Pong.java
@@ -46,7 +46,7 @@ public class Pong {
public int getErrorSize() {
return errors.size();
}
-
+
/** Returns the number of active documents in the backend responding in this Pong, if available */
public Optional<Long> activeDocuments() {
if ( ! pongPacket.isPresent()) return Optional.empty();
diff --git a/container-search/src/main/java/com/yahoo/prelude/SearchDefinition.java b/container-search/src/main/java/com/yahoo/prelude/SearchDefinition.java
index aa76bd5912a..7859a9698d9 100644
--- a/container-search/src/main/java/com/yahoo/prelude/SearchDefinition.java
+++ b/container-search/src/main/java/com/yahoo/prelude/SearchDefinition.java
@@ -96,19 +96,4 @@ public class SearchDefinition {
}
}
- public void fillMatchGroups() {
- for (Index i : indices.values()) {
- Attribute[] matchGroup = i.getMatchGroup();
- if (matchGroup == null) {
- continue;
- }
- for (Attribute a : matchGroup) {
- Index m = getIndex(a.name);
- if (m != null) {
- a.setTokenizedContent(!m.isAttribute());
- }
- }
- }
- }
-
}
diff --git a/container-search/src/main/java/com/yahoo/prelude/cluster/ClusterSearcher.java b/container-search/src/main/java/com/yahoo/prelude/cluster/ClusterSearcher.java
index fd150f975c3..92b6eef906e 100644
--- a/container-search/src/main/java/com/yahoo/prelude/cluster/ClusterSearcher.java
+++ b/container-search/src/main/java/com/yahoo/prelude/cluster/ClusterSearcher.java
@@ -11,7 +11,6 @@ import com.yahoo.concurrent.Receiver.MessageState;
import com.yahoo.container.QrSearchersConfig;
import com.yahoo.container.handler.VipStatus;
import com.yahoo.fs4.mplex.Backend;
-import com.yahoo.container.search.LegacyEmulationConfig;
import com.yahoo.net.HostName;
import com.yahoo.search.dispatch.Dispatcher;
import com.yahoo.prelude.fastsearch.FS4ResourcePool;
@@ -100,7 +99,6 @@ public class ClusterSearcher extends Searcher {
QrSearchersConfig qrsConfig,
ClusterConfig clusterConfig,
DocumentdbInfoConfig documentDbConfig,
- LegacyEmulationConfig emulationConfig,
QrMonitorConfig monitorConfig,
DispatchConfig dispatchConfig,
ClusterInfoConfig clusterInfoConfig,
@@ -133,7 +131,7 @@ public class ClusterSearcher extends Searcher {
SummaryParameters docSumParams = new SummaryParameters(qrsConfig
.com().yahoo().prelude().fastsearch().FastSearcher().docsum()
.defaultclass());
-
+
for (DocumentdbInfoConfig.Documentdb docDb : documentDbConfig.documentdb()) {
String docTypeName = docDb.name();
documentTypes.add(docTypeName);
@@ -146,7 +144,7 @@ public class ClusterSearcher extends Searcher {
if (searchClusterConfig.indexingmode() == STREAMING) {
VdsStreamingSearcher searcher = vdsCluster(fs4ResourcePool.getServerId(),
searchClusterIndex,
- searchClusterConfig, cacheParams, emulationConfig, docSumParams,
+ searchClusterConfig, cacheParams, docSumParams,
documentDbConfig);
addBackendSearcher(searcher);
} else {
@@ -156,7 +154,7 @@ public class ClusterSearcher extends Searcher {
if ( ! isRemote(searchClusterConfig.dispatcher(dispatcherIndex).host())) {
Backend dispatchBackend = createBackend(searchClusterConfig.dispatcher(dispatcherIndex));
FastSearcher searcher = searchDispatch(searchClusterIndex, fs4ResourcePool,
- cacheParams, emulationConfig, docSumParams,
+ cacheParams, docSumParams,
documentDbConfig, dispatchBackend, dispatcher, dispatcherIndex);
addBackendSearcher(searcher);
}
@@ -192,22 +190,21 @@ public class ClusterSearcher extends Searcher {
}
private static ClusterParams makeClusterParams(int searchclusterIndex,
- LegacyEmulationConfig emulConfig,
int dispatchIndex) {
- return new ClusterParams("sc" + searchclusterIndex + ".num" + dispatchIndex, emulConfig);
+ return new ClusterParams("sc" + searchclusterIndex + ".num" + dispatchIndex);
}
private static FastSearcher searchDispatch(int searchclusterIndex,
FS4ResourcePool fs4ResourcePool,
CacheParams cacheParams,
- LegacyEmulationConfig emulConfig,
SummaryParameters docSumParams,
DocumentdbInfoConfig documentdbInfoConfig,
Backend backend,
Dispatcher dispatcher,
int dispatcherIndex) {
- ClusterParams clusterParams = makeClusterParams(searchclusterIndex, emulConfig, dispatcherIndex);
- return new FastSearcher(backend, fs4ResourcePool, dispatcher, docSumParams, clusterParams, cacheParams,
+ ClusterParams clusterParams = makeClusterParams(searchclusterIndex,
+ dispatcherIndex);
+ return new FastSearcher(backend, fs4ResourcePool, dispatcher, docSumParams, clusterParams, cacheParams,
documentdbInfoConfig);
}
@@ -215,14 +212,13 @@ public class ClusterSearcher extends Searcher {
int searchclusterIndex,
QrSearchersConfig.Searchcluster searchClusterConfig,
CacheParams cacheParams,
- LegacyEmulationConfig emulConfig,
SummaryParameters docSumParams,
DocumentdbInfoConfig documentdbInfoConfig)
{
if (searchClusterConfig.searchdef().size() != 1) {
throw new IllegalArgumentException("Search clusters in streaming search shall only contain a single searchdefinition : " + searchClusterConfig.searchdef());
}
- ClusterParams clusterParams = makeClusterParams(searchclusterIndex, emulConfig, 0);
+ ClusterParams clusterParams = makeClusterParams(searchclusterIndex, 0);
VdsStreamingSearcher searcher = (VdsStreamingSearcher) VespaBackEndSearcher
.getSearcher("com.yahoo.vespa.streamingvisitors.VdsStreamingSearcher");
searcher.setSearchClusterConfigId(searchClusterConfig.rankprofiles().configid());
@@ -319,7 +315,7 @@ public class ClusterSearcher extends Searcher {
if (invalidInDocTypes != null && !invalidInDocTypes.isEmpty()) {
String plural = invalidInDocTypes.size() > 1 ? "s" : "";
- return new Result(query,
+ return new Result(query,
ErrorMessage.createInvalidQueryParameter("Requested rank profile '" + rankProfile +
"' is undefined for document type" + plural + " '" +
StringUtils.join(invalidInDocTypes.iterator(), ", ") + "'"));
@@ -384,7 +380,7 @@ public class ClusterSearcher extends Searcher {
if (query.getTimeout() <= maxQueryTimeout) return;
if (query.isTraceable(2)) {
- query.trace("Query timeout (" + query.getTimeout() + " ms) > max query timeout (" +
+ query.trace("Query timeout (" + query.getTimeout() + " ms) > max query timeout (" +
maxQueryTimeout + " ms). Setting timeout to " + maxQueryTimeout + " ms.", 2);
}
query.setTimeout(maxQueryTimeout);
diff --git a/container-search/src/main/java/com/yahoo/prelude/fastsearch/ClusterParams.java b/container-search/src/main/java/com/yahoo/prelude/fastsearch/ClusterParams.java
index 3dfa506a967..2787447e791 100644
--- a/container-search/src/main/java/com/yahoo/prelude/fastsearch/ClusterParams.java
+++ b/container-search/src/main/java/com/yahoo/prelude/fastsearch/ClusterParams.java
@@ -1,8 +1,6 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.prelude.fastsearch;
-import com.yahoo.container.search.LegacyEmulationConfig;
-
/**
* Helper class for carrying around cluster-related
* config parameters to the FastSearcher class.
@@ -12,21 +10,12 @@ import com.yahoo.container.search.LegacyEmulationConfig;
public class ClusterParams {
public final String searcherName;
- public final LegacyEmulationConfig emulation;
-
- /**
- * For testcases only
- */
- public ClusterParams(String name) {
- this(name, new LegacyEmulationConfig(new LegacyEmulationConfig.Builder()));
- }
/**
* Make up full ClusterParams
*/
- public ClusterParams(String name, LegacyEmulationConfig cfg) {
+ public ClusterParams(String name) {
this.searcherName = name;
- this.emulation = cfg;
}
}
diff --git a/container-search/src/main/java/com/yahoo/prelude/fastsearch/DocsumDefinition.java b/container-search/src/main/java/com/yahoo/prelude/fastsearch/DocsumDefinition.java
index cdf696ebe1e..20615a099b6 100644
--- a/container-search/src/main/java/com/yahoo/prelude/fastsearch/DocsumDefinition.java
+++ b/container-search/src/main/java/com/yahoo/prelude/fastsearch/DocsumDefinition.java
@@ -4,7 +4,6 @@ package com.yahoo.prelude.fastsearch;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.yahoo.data.access.Inspector;
-import com.yahoo.container.search.LegacyEmulationConfig;
import java.util.ArrayList;
import java.util.HashMap;
@@ -41,8 +40,7 @@ public class DocsumDefinition {
this.fieldNameToIndex = fieldNameToIndexBuilder.build();
}
- // TODO: Remove LegacyEmulationConfig (the config, not just the usage) on Vespa 7
- DocsumDefinition(DocumentdbInfoConfig.Documentdb.Summaryclass config, LegacyEmulationConfig emulConfig) {
+ DocsumDefinition(DocumentdbInfoConfig.Documentdb.Summaryclass config) {
this.name = config.name();
List<DocsumField> fieldsBuilder = new ArrayList<>();
@@ -51,7 +49,7 @@ public class DocsumDefinition {
for (DocumentdbInfoConfig.Documentdb.Summaryclass.Fields field : config.fields()) {
// no, don't switch the order of the two next lines :)
fieldNameToIndexBuilder.put(field.name(), fieldsBuilder.size());
- fieldsBuilder.add(DocsumField.create(field.name(), field.type(), emulConfig));
+ fieldsBuilder.add(DocsumField.create(field.name(), field.type()));
if (field.dynamic())
dynamic = true;
}
diff --git a/container-search/src/main/java/com/yahoo/prelude/fastsearch/DocsumDefinitionSet.java b/container-search/src/main/java/com/yahoo/prelude/fastsearch/DocsumDefinitionSet.java
index 07997f0c8f6..7745a71b24f 100644
--- a/container-search/src/main/java/com/yahoo/prelude/fastsearch/DocsumDefinitionSet.java
+++ b/container-search/src/main/java/com/yahoo/prelude/fastsearch/DocsumDefinitionSet.java
@@ -7,7 +7,6 @@ import com.yahoo.data.access.Inspector;
import com.yahoo.slime.Slime;
import com.yahoo.data.access.slime.SlimeAdapter;
import com.yahoo.prelude.ConfigurationException;
-import com.yahoo.container.search.LegacyEmulationConfig;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
@@ -31,27 +30,15 @@ public final class DocsumDefinitionSet {
private final static Logger log = Logger.getLogger(DocsumDefinitionSet.class.getName());
private final Map<String, DocsumDefinition> definitionsByName;
- private final LegacyEmulationConfig emulationConfig;
public DocsumDefinitionSet(DocumentdbInfoConfig.Documentdb config) {
- this(config, new LegacyEmulationConfig(new LegacyEmulationConfig.Builder()));
- }
-
- public DocsumDefinitionSet(DocumentdbInfoConfig.Documentdb config, LegacyEmulationConfig emulConfig) {
- this(toDocsums(config, emulConfig), emulConfig);
+ this(toDocsums(config));
}
public DocsumDefinitionSet(Collection<DocsumDefinition> docsumDefinitions) {
- this(docsumDefinitions, new LegacyEmulationConfig(new LegacyEmulationConfig.Builder()));
- }
-
- public DocsumDefinitionSet(Collection<DocsumDefinition> docsumDefinitions, LegacyEmulationConfig emulConfig) {
this.definitionsByName = ImmutableMap.copyOf(docsumDefinitions.stream().collect(Collectors.toMap(DocsumDefinition::getName, p -> p)));
- this.emulationConfig = emulConfig;
}
- public LegacyEmulationConfig legacyEmulationConfig() { return emulationConfig; }
-
/**
* Returns the summary definition of the given name, or the default if not found.
*
@@ -111,10 +98,10 @@ public final class DocsumDefinitionSet {
return definitionsByName.size();
}
- private static Collection<DocsumDefinition> toDocsums(DocumentdbInfoConfig.Documentdb config, LegacyEmulationConfig emulConfig) {
+ private static Collection<DocsumDefinition> toDocsums(DocumentdbInfoConfig.Documentdb config) {
Collection<DocsumDefinition> docsums = new ArrayList<>();
for (int i = 0; i < config.summaryclass().size(); ++i)
- docsums.add(new DocsumDefinition(config.summaryclass(i), emulConfig));
+ docsums.add(new DocsumDefinition(config.summaryclass(i)));
if (docsums.isEmpty())
log.warning("No summary classes found in DocumentdbInfoConfig.Documentdb");
return docsums;
diff --git a/container-search/src/main/java/com/yahoo/prelude/fastsearch/DocsumField.java b/container-search/src/main/java/com/yahoo/prelude/fastsearch/DocsumField.java
index 777919286dd..4f52ef91725 100644
--- a/container-search/src/main/java/com/yahoo/prelude/fastsearch/DocsumField.java
+++ b/container-search/src/main/java/com/yahoo/prelude/fastsearch/DocsumField.java
@@ -1,7 +1,6 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.prelude.fastsearch;
-import com.yahoo.container.search.LegacyEmulationConfig;
import com.yahoo.data.access.Inspector;
import com.yahoo.log.LogLevel;
@@ -31,19 +30,14 @@ public abstract class DocsumField {
constructors.put(typename, constructor);
}
- DocsumField create(String typename, String name, LegacyEmulationConfig emulConfig)
+ DocsumField create(String typename, String name)
throws InstantiationException, IllegalAccessException,
IllegalArgumentException, InvocationTargetException {
DocsumField f = constructors.get(typename).newInstance(name);
- f.emulConfig = emulConfig;
return f;
}
}
- private LegacyEmulationConfig emulConfig;
-
- final LegacyEmulationConfig getEmulConfig() { return emulConfig; }
-
static {
fieldFactory = new FieldFactory();
@@ -75,14 +69,9 @@ public abstract class DocsumField {
this.name = name;
}
- /* For unit test only */
public static DocsumField create(String name, String typename) {
- return create(name, typename, new LegacyEmulationConfig(new LegacyEmulationConfig.Builder()));
- }
-
- public static DocsumField create(String name, String typename, LegacyEmulationConfig emulConfig) {
try {
- return fieldFactory.create(typename, name, emulConfig);
+ return fieldFactory.create(typename, name);
} catch (Exception e) {
throw new RuntimeException("Unknown field type '" + typename + "'", e);
}
diff --git a/container-search/src/main/java/com/yahoo/prelude/fastsearch/DocumentDatabase.java b/container-search/src/main/java/com/yahoo/prelude/fastsearch/DocumentDatabase.java
index 0ae0983a1ae..aa492524c83 100644
--- a/container-search/src/main/java/com/yahoo/prelude/fastsearch/DocumentDatabase.java
+++ b/container-search/src/main/java/com/yahoo/prelude/fastsearch/DocumentDatabase.java
@@ -2,7 +2,6 @@
package com.yahoo.prelude.fastsearch;
import com.google.common.collect.ImmutableMap;
-import com.yahoo.container.search.LegacyEmulationConfig;
import java.util.ArrayList;
import java.util.Collection;
@@ -29,8 +28,8 @@ public class DocumentDatabase {
private final ImmutableMap<String, RankProfile> rankProfiles;
- public DocumentDatabase(DocumentdbInfoConfig.Documentdb documentDb, LegacyEmulationConfig emulConfig) {
- this(documentDb.name(), new DocsumDefinitionSet(documentDb, emulConfig), toRankProfiles(documentDb.rankprofile()));
+ public DocumentDatabase(DocumentdbInfoConfig.Documentdb documentDb) {
+ this(documentDb.name(), new DocsumDefinitionSet(documentDb), toRankProfiles(documentDb.rankprofile()));
}
public DocumentDatabase(String name, DocsumDefinitionSet docsumDefinitionSet, Collection<RankProfile> rankProfiles) {
diff --git a/container-search/src/main/java/com/yahoo/prelude/fastsearch/FastHit.java b/container-search/src/main/java/com/yahoo/prelude/fastsearch/FastHit.java
index 28d426cec06..8d73f6795d4 100644
--- a/container-search/src/main/java/com/yahoo/prelude/fastsearch/FastHit.java
+++ b/container-search/src/main/java/com/yahoo/prelude/fastsearch/FastHit.java
@@ -77,7 +77,6 @@ public class FastHit extends Hit {
// Note: This constructor is only used for tests, production use is always of the empty constructor
public FastHit(String uri, double relevance, String source) {
setId(uri);
- super.setField("uri", uri); // TODO: Remove on Vespa 7
setRelevance(new Relevance(relevance));
setSource(source);
types().add("summary");
@@ -97,13 +96,6 @@ public class FastHit extends Hit {
URI uri = super.getId();
if (uri != null) return uri;
- // TODO: Remove on Vespa 7, this should be one of the last vestiges of URL field magic
- Object uriField = getField("uri");
- if (uriField != null) {
- setId(uriField.toString());
- return super.getId();
- }
-
// Fallback to index:[source]/[partid]/[id]
if (indexUri != null) return indexUri;
StringBuilder sb = new StringBuilder(64);
@@ -315,21 +307,6 @@ public class FastHit extends Hit {
return super.hasFields();
}
- /**
- * Changes the key under which a value is found. This is useful because it allows keys to be changed
- * without accessing the value (which may be lazily created).
- *
- * @deprecated do not use
- */
- @Deprecated // OK
- @Override
- @SuppressWarnings("deprecation")
- public void changeFieldKey(String oldKey, String newKey) {
- Object value = removeField(oldKey);
- if (value != null)
- setField(newKey, value);
- }
-
private Object getSummaryValue(String name) {
if (removedFields != null && removedFields.contains(name))
return null;
@@ -357,13 +334,6 @@ public class FastHit extends Hit {
}
}
- /** @deprecated do not use */
- // TODO: Make private on Vespa 7
- @Deprecated // OK
- public static String asHexString(GlobalId gid) {
- return asHexString(new StringBuilder(), gid).toString();
- }
-
private static StringBuilder asHexString(StringBuilder sb, GlobalId gid) {
byte[] rawGid = gid.getRawId();
for (byte b : rawGid) {
@@ -539,7 +509,7 @@ public class FastHit extends Hit {
DocsumField fieldType = type.getField(name);
if (fieldType == null) return null;
Inspector fieldValue = data.field(name);
- if ( ! fieldValue.valid() && ! fieldType.getEmulConfig().forceFillEmptyFields()) return null;
+ if ( ! fieldValue.valid()) return null;
return fieldType.convert(fieldValue);
}
diff --git a/container-search/src/main/java/com/yahoo/prelude/fastsearch/FeatureDataField.java b/container-search/src/main/java/com/yahoo/prelude/fastsearch/FeatureDataField.java
index 28c63aa2d3a..1f60dd3d1cf 100644
--- a/container-search/src/main/java/com/yahoo/prelude/fastsearch/FeatureDataField.java
+++ b/container-search/src/main/java/com/yahoo/prelude/fastsearch/FeatureDataField.java
@@ -3,7 +3,6 @@ package com.yahoo.prelude.fastsearch;
import com.yahoo.data.access.Inspector;
import com.yahoo.data.access.Type;
-import com.yahoo.container.search.LegacyEmulationConfig;
import com.yahoo.search.result.FeatureData;
/**
@@ -13,7 +12,7 @@ import com.yahoo.search.result.FeatureData;
*/
public class FeatureDataField extends LongstringField {
- public FeatureDataField (String name) {
+ public FeatureDataField(String name) {
super(name);
}
@@ -25,23 +24,12 @@ public class FeatureDataField extends LongstringField {
@Override
public Object convert(Inspector value) {
if (! value.valid()) {
- if (getEmulConfig().stringBackedFeatureData()) {
- return "";
- } else if (getEmulConfig().forceFillEmptyFields()) {
- return new FeatureData(com.yahoo.data.access.simple.Value.empty());
- } else {
- return null;
- }
+ return null;
}
if (value.type() == Type.STRING) {
return value.asString();
}
- FeatureData obj = new FeatureData(value);
- if (getEmulConfig().stringBackedFeatureData()) {
- return obj.toJson();
- } else {
- return obj;
- }
+ return new FeatureData(value);
}
}
diff --git a/container-search/src/main/java/com/yahoo/prelude/fastsearch/StructDataField.java b/container-search/src/main/java/com/yahoo/prelude/fastsearch/StructDataField.java
index 9521854477a..18986667a6c 100644
--- a/container-search/src/main/java/com/yahoo/prelude/fastsearch/StructDataField.java
+++ b/container-search/src/main/java/com/yahoo/prelude/fastsearch/StructDataField.java
@@ -4,7 +4,6 @@ package com.yahoo.prelude.fastsearch;
import com.yahoo.search.result.StructuredData;
import com.yahoo.data.access.Inspector;
import com.yahoo.data.access.Type;
-import com.yahoo.container.search.LegacyEmulationConfig;
import com.yahoo.prelude.hitfield.JSONString;
/**
@@ -23,7 +22,7 @@ public class StructDataField extends JSONField {
@Override
public Object convert(Inspector value) {
- if (getEmulConfig().stringBackedStructuredData() || value.type() == Type.STRING) {
+ if (value.type() == Type.STRING) {
return super.convert(value);
}
return new StructuredData(value);
diff --git a/container-search/src/main/java/com/yahoo/prelude/fastsearch/VespaBackEndSearcher.java b/container-search/src/main/java/com/yahoo/prelude/fastsearch/VespaBackEndSearcher.java
index e8f5d7110f7..d6e87e58fd8 100644
--- a/container-search/src/main/java/com/yahoo/prelude/fastsearch/VespaBackEndSearcher.java
+++ b/container-search/src/main/java/com/yahoo/prelude/fastsearch/VespaBackEndSearcher.java
@@ -177,7 +177,7 @@ public abstract class VespaBackEndSearcher extends PingableSearcher {
if (documentdbInfoConfig != null) {
for (DocumentdbInfoConfig.Documentdb docDb : documentdbInfoConfig.documentdb()) {
- DocumentDatabase db = new DocumentDatabase(docDb, clusterParams.emulation);
+ DocumentDatabase db = new DocumentDatabase(docDb);
if (documentDbs.isEmpty()) {
defaultDocumentDb = db;
}
@@ -372,7 +372,7 @@ public abstract class VespaBackEndSearcher extends PingableSearcher {
s.append(" ranking.queryCache=true");
}
if (query.getGroupingSessionCache() || query.getRanking().getQueryCache()) {
- s.append(" sessionId=").append(query.getSessionId(false));
+ s.append(" sessionId=").append(query.getSessionId());
}
List<Grouping> grouping = GroupingExecutor.getGroupingList(query);
diff --git a/container-search/src/main/java/com/yahoo/prelude/fastsearch/XMLField.java b/container-search/src/main/java/com/yahoo/prelude/fastsearch/XMLField.java
index cb115502468..d768dda2657 100644
--- a/container-search/src/main/java/com/yahoo/prelude/fastsearch/XMLField.java
+++ b/container-search/src/main/java/com/yahoo/prelude/fastsearch/XMLField.java
@@ -31,10 +31,10 @@ public class XMLField extends DocsumField {
@Override
public Object convert(Inspector value) {
/* In Vespa 6 the backend will send an XML-formatted string to represent
- * positions data. This will change in next version to sending an array
- * of objects instead, suitable for the PositionsData class.
+ * positions data. This will change in next version to sending an object
+ * or an array of objects instead, suitable for the PositionsData class.
*/
- if (value.type() == Type.ARRAY) {
+ if (value.type() == Type.OBJECT || value.type() == Type.ARRAY) {
return new PositionsData(value);
}
return convert(value.asString(""));
diff --git a/container-search/src/main/java/com/yahoo/prelude/hitfield/FieldIterator.java b/container-search/src/main/java/com/yahoo/prelude/hitfield/FieldIterator.java
index c8dc87aeb52..3c61678bbde 100644
--- a/container-search/src/main/java/com/yahoo/prelude/hitfield/FieldIterator.java
+++ b/container-search/src/main/java/com/yahoo/prelude/hitfield/FieldIterator.java
@@ -7,7 +7,7 @@ import java.util.ListIterator;
/**
* A specialized list iterator to manipulate FieldParts in HitField objects.
*
- * @author <a href="mailto:steinar@yahoo-inc.com">Steinar Knutsen</a>
+ * @author Steinar Knutsen
*/
public class FieldIterator implements ListIterator<FieldPart> {
diff --git a/container-search/src/main/java/com/yahoo/prelude/hitfield/HitField.java b/container-search/src/main/java/com/yahoo/prelude/hitfield/HitField.java
index f6619a32a2b..2702da099be 100644
--- a/container-search/src/main/java/com/yahoo/prelude/hitfield/HitField.java
+++ b/container-search/src/main/java/com/yahoo/prelude/hitfield/HitField.java
@@ -24,7 +24,7 @@ public class HitField {
private boolean xmlProperty;
private List<FieldPart> tokenizedContent = null;
- private String content = null;
+ private String content;
private Object original;
@@ -48,7 +48,7 @@ public class HitField {
/**
* @param f The field name
* @param c The field content
- * @param cjk true if this is a cjk-document
+ * @param cjk true if the content is CJK text
*/
public HitField(String f, String c, boolean cjk) {
this(f, c, cjk, false);
@@ -57,7 +57,7 @@ public class HitField {
/**
* @param f The field name
* @param c The field content
- * @param cjk true if this is a cjk-document
+ * @param cjk true if the content is CJK text
*/
public HitField(String f, XMLString c, boolean cjk) {
this(f, c.toString(), cjk, true);
@@ -66,7 +66,7 @@ public class HitField {
/**
* @param f The field name
* @param c The field content
- * @param cjk true if this is a cjk-document
+ * @param cjk true if the content is CJK text
* @param xmlProperty true if this should not quote XML syntax
*/
public HitField(String f, String c, boolean cjk, boolean xmlProperty) {
@@ -279,9 +279,8 @@ public class HitField {
// Must null content reference _before_ calling getContent()
content = null;
}
- /**
- * @return the content of this field
- */
+
+ /** Returns the content of this field */
public String getContent() {
if (content == null) {
StringBuilder buf = new StringBuilder();
@@ -294,13 +293,8 @@ public class HitField {
return content;
}
- /**
- * @return the content of this field, using the arguments as bolding
- * tags
- */
- public String getContent(String boldOpenTag,
- String boldCloseTag,
- String separatorTag) {
+ /** Returns the content of this field, using the arguments as bolding tags */
+ public String getContent(String boldOpenTag, String boldCloseTag, String separatorTag) {
StringBuilder buf = new StringBuilder();
Iterator<FieldPart> iter = ensureTokenized().iterator();
while(iter.hasNext()) {
@@ -372,8 +366,9 @@ public class HitField {
}
return xml.toString();
}
+
/**
- * @return the content of the field, stripped of markup
+ * Returns the content of the field, stripped of markup
*/
public String bareContent(boolean XMLQuote, boolean inAttribute) {
StringBuilder bareContent = new StringBuilder();
diff --git a/container-search/src/main/java/com/yahoo/prelude/hitfield/JSONString.java b/container-search/src/main/java/com/yahoo/prelude/hitfield/JSONString.java
index 06db012309e..eee7b310d13 100644
--- a/container-search/src/main/java/com/yahoo/prelude/hitfield/JSONString.java
+++ b/container-search/src/main/java/com/yahoo/prelude/hitfield/JSONString.java
@@ -86,6 +86,7 @@ public class JSONString implements Inspectable {
didInitContent = true;
}
+ @Override
public String toString() {
if (value != null) {
return renderFromInspector();
diff --git a/container-search/src/main/java/com/yahoo/prelude/hitfield/TokenFieldIterator.java b/container-search/src/main/java/com/yahoo/prelude/hitfield/TokenFieldIterator.java
index 95100dd4d39..beda005152c 100644
--- a/container-search/src/main/java/com/yahoo/prelude/hitfield/TokenFieldIterator.java
+++ b/container-search/src/main/java/com/yahoo/prelude/hitfield/TokenFieldIterator.java
@@ -8,7 +8,7 @@ import java.util.NoSuchElementException;
/**
* A specialized list iterator to manipulate tokens in HitField objects.
*
- * @author <a href="mailto:steinar@yahoo-inc.com">Steinar Knutsen</a>
+ * @author Steinar Knutsen
*/
public class TokenFieldIterator implements ListIterator<FieldPart> {
diff --git a/container-search/src/main/java/com/yahoo/prelude/logging/AccessLogEntry.java b/container-search/src/main/java/com/yahoo/prelude/logging/AccessLogEntry.java
deleted file mode 100644
index f9faf242350..00000000000
--- a/container-search/src/main/java/com/yahoo/prelude/logging/AccessLogEntry.java
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-package com.yahoo.prelude.logging;
-
-/**
- * Hollow compatibility class for com.yahoo.container.logging.AccessLogEntry.
- *
- * @author Steinar Knutsen
- * @deprecated do not use
- */
-// TODO: Remove on Vespa 7
-@Deprecated // OK
-public class AccessLogEntry extends com.yahoo.container.logging.AccessLogEntry {
-
- public AccessLogEntry() {
- super();
- }
-
-}
diff --git a/container-search/src/main/java/com/yahoo/prelude/logging/package-info.java b/container-search/src/main/java/com/yahoo/prelude/logging/package-info.java
deleted file mode 100644
index 01126ec3484..00000000000
--- a/container-search/src/main/java/com/yahoo/prelude/logging/package-info.java
+++ /dev/null
@@ -1,5 +0,0 @@
-// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-@ExportPackage
-package com.yahoo.prelude.logging;
-
-import com.yahoo.osgi.annotation.ExportPackage;
diff --git a/container-search/src/main/java/com/yahoo/prelude/query/parser/AdvancedParser.java b/container-search/src/main/java/com/yahoo/prelude/query/parser/AdvancedParser.java
index f6f96ae215c..244d895f357 100644
--- a/container-search/src/main/java/com/yahoo/prelude/query/parser/AdvancedParser.java
+++ b/container-search/src/main/java/com/yahoo/prelude/query/parser/AdvancedParser.java
@@ -13,7 +13,7 @@ import static com.yahoo.prelude.query.parser.Token.Kind.NUMBER;
* @author Steinar Knutsen
* @deprecated since 5.11, YQL+ should be used for formal queries
*/
-@Deprecated // OK DO NOT REMOVE (we'll keep this around longer)
+@Deprecated // DO NOT REMOVE (we'll keep this around longer)
public class AdvancedParser extends StructuredParser {
public AdvancedParser(ParserEnvironment environment) {
diff --git a/container-search/src/main/java/com/yahoo/prelude/querytransform/IndexCombinatorSearcher.java b/container-search/src/main/java/com/yahoo/prelude/querytransform/IndexCombinatorSearcher.java
deleted file mode 100644
index ff603a64725..00000000000
--- a/container-search/src/main/java/com/yahoo/prelude/querytransform/IndexCombinatorSearcher.java
+++ /dev/null
@@ -1,361 +0,0 @@
-// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-package com.yahoo.prelude.querytransform;
-
-import static com.yahoo.prelude.querytransform.PhrasingSearcher.PHRASE_REPLACEMENT;
-
-import com.yahoo.component.chain.dependencies.After;
-import com.yahoo.component.chain.dependencies.Before;
-import com.yahoo.component.chain.dependencies.Provides;
-import com.yahoo.log.LogLevel;
-import com.yahoo.prelude.Index;
-import com.yahoo.prelude.Index.Attribute;
-import com.yahoo.prelude.IndexFacts;
-import com.yahoo.prelude.query.*;
-import com.yahoo.search.Query;
-import com.yahoo.search.Result;
-import com.yahoo.search.Searcher;
-import com.yahoo.search.searchchain.Execution;
-import com.yahoo.search.searchchain.PhaseNames;
-
-import java.util.*;
-
-/**
- * Searcher to rewrite queries to achieve mixed recall between indices and
- * memory attributes.
- *
- * @author Steinar Knutsen
- * @deprecated do not use
- */
-// TODO: Remove on Vespa 7 (not necessary any more)
-@After({PhaseNames.RAW_QUERY, PHRASE_REPLACEMENT})
-@Before(PhaseNames.TRANSFORMED_QUERY)
-@Provides(IndexCombinatorSearcher.MIXED_RECALL_REWRITE)
-@Deprecated // OK
-public class IndexCombinatorSearcher extends Searcher {
-
- public static final String MIXED_RECALL_REWRITE = "MixedRecallRewrite";
-
- private static class ArrayComparator implements Comparator<Attribute[]> {
- /**
- * Note, this ignores if there is a difference in whether to
- * attributes have tokenized content. (If this is the case,
- * we are having worse problems anyway.)
- */
- public int compare(Attribute[] o1, Attribute[] o2 ) {
- if (o1.length < o2.length) {
- return -1;
- } else if (o1.length > o2.length) {
- return 1;
- }
- int limit = o1.length;
- for (int i = 0; i < limit; ++i) {
- int r = o1[i].name.compareTo(o2[i].name);
- if (r != 0) {
- return r;
- }
- }
- return 0;
- }
- }
-
- private final ArrayComparator comparator = new ArrayComparator();
-
- private enum RewriteStrategies {
- NONE, CHEAP_AND, EXPENSIVE_AND, FLAT
- }
-
- @Override
- public Result search(Query query, Execution execution) {
- Item root = query.getModel().getQueryTree().getRoot();
- IndexFacts.Session session = execution.context().getIndexFacts().newSession(query);
- String oldQuery = (query.getTraceLevel() >= 2) ? root.toString() : "";
-
- if (root instanceof BlockItem || root instanceof PhraseItem) {
- root = convertSinglePhraseOrBlock(root, session);
- } else if (root instanceof CompositeItem) {
- root = rewrite((CompositeItem) root, session);
- }
- query.getModel().getQueryTree().setRoot(root);
-
- if ((query.getTraceLevel() >= 2) && !(oldQuery.equals(root.toString()))) {
- query.trace("Rewriting for mixed recall between indices and attributes", true, 2);
- }
- return execution.search(query);
- }
-
- private RewriteStrategies chooseRewriteStrategy(CompositeItem c, IndexFacts.Session session) {
- if (c instanceof OrItem) {
- return RewriteStrategies.FLAT;
- } else if (!(c instanceof AndItem)) {
- return RewriteStrategies.NONE;
- }
- Map<Attribute[], Integer> m = new TreeMap<>(comparator);
- for (Iterator<Item> i = c.getItemIterator(); i.hasNext();) {
- Item j = i.next();
- if (j instanceof BlockItem || j instanceof PhraseItem) {
- Attribute[] attributes= getIndices((HasIndexItem) j, session);
- if (attributes == null) {
- continue;
- }
- Integer count = m.get(attributes);
- if (count == null) {
- count = 1;
- } else {
- count = count.intValue() + 1;
- }
- m.put(attributes, count);
- }
- }
-
- if (m.size() == 0) {
- return RewriteStrategies.NONE;
- }
-
- int singles = 0;
- int pairs = 0;
- int higher = 0;
- // count the number of sets being associated with 1, 2 or more terms
- for (Integer i : m.values()) {
- switch (i.intValue()) {
- case 1:
- ++singles;
- break;
- case 2:
- pairs += 2;
- break;
- default:
- ++higher;
- break;
- }
- }
- if (higher == 0 && pairs + singles <= 2) {
- return RewriteStrategies.EXPENSIVE_AND;
- } else {
- return RewriteStrategies.CHEAP_AND;
- }
- }
-
- private CompositeItem rewriteNot(NotItem not, IndexFacts.Session session) {
- Item positive = not.getItem(0);
- if (positive instanceof BlockItem || positive instanceof PhraseItem) {
- positive = convertSinglePhraseOrBlock(positive, session);
- not.setItem(0, positive);
- } else if (positive instanceof CompositeItem) {
- CompositeItem c = (CompositeItem) positive;
- positive = rewrite(c, session);
- not.setItem(0, positive);
- }
-
- int length = not.getItemCount();
- // no need for keeping proximity in the negative branches, so we
- // convert them one by one, _and_ always uses cheap transform
- for (int i = 1; i < length; ++i) {
- Item exclusion = not.getItem(i);
- if (exclusion instanceof BlockItem || exclusion instanceof PhraseItem) {
- exclusion = convertSinglePhraseOrBlock(exclusion, session);
- not.setItem(i, exclusion);
- } else if (exclusion instanceof CompositeItem) {
- CompositeItem c = (CompositeItem) exclusion;
- switch (chooseRewriteStrategy(c, session)) {
- case NONE:
- c = traverse(c, session);
- break;
- case CHEAP_AND:
- case EXPENSIVE_AND:
- c = cheapTransform(c, session);
- break;
- default:
- c = flatTransform(c, session);
- break;
- }
- not.setItem(i, c);
- }
- }
- return not;
- }
-
- private Item rewrite(CompositeItem c, IndexFacts.Session session) {
- if (c instanceof NotItem) {
- c = rewriteNot((NotItem) c, session);
- return c;
- } else {
- switch (chooseRewriteStrategy(c, session)) {
- case NONE:
- c = traverse(c, session);
- break;
- case CHEAP_AND:
- c = cheapTransform(c, session);
- break;
- case EXPENSIVE_AND:
- c = expensiveTransform((AndItem) c, session);
- break;
- case FLAT:
- c = flatTransform(c, session);
- break;
- default:
- break;
- }
- }
- return c;
- }
-
- private CompositeItem traverse(CompositeItem c, IndexFacts.Session session) {
- int length = c.getItemCount();
- for (int i = 0; i < length; ++i) {
- Item word = c.getItem(i);
- if (word instanceof CompositeItem && !(word instanceof PhraseItem) && !(word instanceof BlockItem)) {
- c.setItem(i, rewrite((CompositeItem) word, session));
- }
- }
- return c;
- }
-
- private CompositeItem expensiveTransform(AndItem c, IndexFacts.Session session) {
- int[] indices = new int[2];
- int items = 0;
- int length = c.getItemCount();
- Attribute[][] names = new Attribute[2][];
- CompositeItem result = null;
- for (int i = 0; i < length; ++i) {
- Item word = c.getItem(i);
- if (word instanceof BlockItem || word instanceof PhraseItem) {
- Attribute[] attributes = getIndices((HasIndexItem) word, session);
- if (attributes == null) {
- continue;
- }
- // this throwing an out of bounds if more than two candidates is intentional
- names[items] = attributes;
- indices[items++] = i;
- } else if (word instanceof CompositeItem) {
- c.setItem(i, rewrite((CompositeItem) word, session));
- }
- }
- switch (items) {
- case 1:
- result = linearAnd(c, names[0], indices[0]);
- break;
- case 2:
- result = quadraticAnd(c, names[0], names[1], indices[0], indices[1]);
- break;
- default:
- // should never happen
- getLogger().log(
- LogLevel.WARNING,
- "Unexpected number of items for mixed recall, got " + items
- + ", expected 1 or 2.");
- break;
- }
- return result;
- }
-
- private Attribute[] getIndices(HasIndexItem block, IndexFacts.Session session) {
- return session.getIndex(block.getIndexName()).getMatchGroup();
- }
-
- private OrItem linearAnd(AndItem c, Attribute[] names, int brancherIndex) {
- OrItem or = new OrItem();
- for (int i = 0; i < names.length; ++i) {
- AndItem duck = (AndItem) c.clone();
- Item b = retarget(duck.getItem(brancherIndex), names[i]);
- duck.setItem(brancherIndex, b);
- or.addItem(duck);
- }
- return or;
- }
-
- private OrItem quadraticAnd(AndItem c, Attribute[] firstNames, Attribute[] secondNames, int firstBrancher, int secondBrancher) {
- OrItem or = new OrItem();
- for (int i = 0; i < firstNames.length; ++i) {
- for (int j = 0; j < secondNames.length; ++j) {
- AndItem duck = (AndItem) c.clone();
- Item b = retarget(duck.getItem(firstBrancher), firstNames[i]);
- duck.setItem(firstBrancher, b);
- b = retarget(duck.getItem(secondBrancher), secondNames[j]);
- duck.setItem(secondBrancher, b);
- or.addItem(duck);
- }
- }
- return or;
- }
-
- private CompositeItem flatTransform(CompositeItem c, IndexFacts.Session session) {
- int maxIndex = c.getItemCount() - 1;
- for (int i = maxIndex; i >= 0; --i) {
- Item word = c.getItem(i);
- if (word instanceof BlockItem || word instanceof PhraseItem) {
- Attribute[] attributes = getIndices((HasIndexItem) word, session);
- if (attributes == null) {
- continue;
- }
- c.removeItem(i);
- for (Attribute name : attributes) {
- Item term = word.clone();
- Item forNewIndex = retarget(term, name);
- c.addItem(forNewIndex);
- }
- } else if (word instanceof CompositeItem) {
- c.setItem(i, rewrite((CompositeItem) word, session));
- }
- }
- return c;
- }
-
- private CompositeItem cheapTransform(CompositeItem c, IndexFacts.Session session) {
- if (c instanceof OrItem) {
- return flatTransform(c, session);
- }
- int length = c.getItemCount();
- for (int i = 0; i < length; ++i) {
- Item j = c.getItem(i);
- if (j instanceof BlockItem || j instanceof PhraseItem) {
- Attribute[] attributes = getIndices((HasIndexItem) j, session);
- if (attributes == null) {
- continue;
- }
- CompositeItem or = searchAllForItem(j, attributes);
- c.setItem(i, or);
- } else if (j instanceof CompositeItem) {
- c.setItem(i, rewrite((CompositeItem) j, session));
- }
- }
- return c;
- }
-
- private OrItem searchAllForItem(Item word, Attribute[] attributes) {
- OrItem or = new OrItem();
- for (Attribute name : attributes) {
- Item term = word.clone();
- term = retarget(term, name);
- or.addItem(term);
- }
- return or;
- }
-
- private Item retarget(Item word, Attribute newIndex) {
- if (word instanceof PhraseItem && !newIndex.isTokenizedContent()) {
- PhraseItem asPhrase = (PhraseItem) word;
- WordItem newWord = new WordItem(asPhrase.getIndexedString(), newIndex.name, false);
- return newWord;
- } else if (word instanceof IndexedItem) {
- word.setIndexName(newIndex.name);
- } else if (word instanceof CompositeItem) {
- CompositeItem asComposite = (CompositeItem) word;
- for (Iterator<Item> i = asComposite.getItemIterator(); i.hasNext();) {
- Item segment = i.next();
- segment.setIndexName(newIndex.name);
- }
- }
- return word;
- }
-
- private Item convertSinglePhraseOrBlock(Item item, IndexFacts.Session session) {
- Item newItem;
- Attribute[] attributes = getIndices((HasIndexItem) item, session);
- if (attributes == null) {
- return item;
- }
- newItem = searchAllForItem(item, attributes);
- return newItem;
- }
-
-}
diff --git a/container-search/src/main/java/com/yahoo/prelude/searcher/BlendingSearcher.java b/container-search/src/main/java/com/yahoo/prelude/searcher/BlendingSearcher.java
index 28d384b0f63..61ce9d98e69 100644
--- a/container-search/src/main/java/com/yahoo/prelude/searcher/BlendingSearcher.java
+++ b/container-search/src/main/java/com/yahoo/prelude/searcher/BlendingSearcher.java
@@ -38,21 +38,20 @@ public class BlendingSearcher extends Searcher {
public static final String BLENDING = "Blending";
- private final String documentId;
+ private final String blendingField;
@Inject
public BlendingSearcher(ComponentId id, QrSearchersConfig cfg) {
super(id);
QrSearchersConfig.Com.Yahoo.Prelude.Searcher.BlendingSearcher s = cfg.com().yahoo().prelude().searcher().BlendingSearcher();
- documentId = s.docid().length() > 0 ? s.docid() : null;
-
+ blendingField = s.docid().length() > 0 ? s.docid() : null;
}
/**
* Only for legacy tests.
*/
- public BlendingSearcher(String blendingDocumentId) {
- this.documentId = blendingDocumentId;
+ public BlendingSearcher(String blendingField) {
+ this.blendingField = blendingField;
}
@Override
@@ -107,7 +106,7 @@ public class BlendingSearcher extends Searcher {
result.hits().setOrderer(groups.get(0).getOrderer());
return result;
} else {
- if (documentId != null) {
+ if (blendingField != null) {
return blendResultsUniquely(result, q, offset, hits, groups, execution);
} else {
return blendResultsDirectly(result, q, offset, hits, groups, execution);
@@ -125,6 +124,7 @@ public class BlendingSearcher extends Searcher {
}
private abstract class DocumentMerger {
+
protected Set<String> documentsToStrip;
protected Result result;
protected HitGroup group;
@@ -137,22 +137,22 @@ public class BlendingSearcher extends Searcher {
return result;
}
- //Since we cannot use prelude.hit#getProperty, we'll have to improvise
private String getProperty(Hit hit, String field) {
+ if ("[id]".equals(field)) return hit.getId().toString();
Object o = hit.getField(field);
return o == null ? null : o.toString();
}
protected void storeID(Hit hit, Execution execution) {
- String id = getProperty(hit, documentId);
+ String id = getProperty(hit, blendingField);
if (id != null) {
documentsToStrip.add(id);
} else {
if (!result.isFilled(result.getQuery().getPresentation().getSummary())) {
fill(result, result.getQuery().getPresentation().getSummary(), execution);
- id = getProperty(hit, documentId);
+ id = getProperty(hit, blendingField);
if (id != null) {
documentsToStrip.add(id);
}
@@ -161,14 +161,14 @@ public class BlendingSearcher extends Searcher {
}
protected boolean known(HitGroup source, Hit hit, Execution execution) {
- String stripID = getProperty(hit, documentId);
+ String stripID = getProperty(hit, blendingField);
if (stripID == null) {
if (!source.isFilled(result.getQuery().getPresentation().getSummary())) {
Result nResult = new Result(result.getQuery());
nResult.hits().add(source);
fill(nResult, nResult.getQuery().getPresentation().getSummary(), execution);
- stripID = getProperty(hit, documentId);
+ stripID = getProperty(hit, blendingField);
if (stripID == null) {
return false;
}
diff --git a/container-search/src/main/java/com/yahoo/prelude/searcher/DocumentSourceSearcher.java b/container-search/src/main/java/com/yahoo/prelude/searcher/DocumentSourceSearcher.java
deleted file mode 100644
index bc3c6665ae2..00000000000
--- a/container-search/src/main/java/com/yahoo/prelude/searcher/DocumentSourceSearcher.java
+++ /dev/null
@@ -1,225 +0,0 @@
-// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-package com.yahoo.prelude.searcher;
-
-import com.yahoo.search.Query;
-import com.yahoo.search.Result;
-import com.yahoo.search.Searcher;
-import com.yahoo.search.result.Hit;
-import com.yahoo.search.searchchain.Execution;
-
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-
-/**
- * <p>Implements a document source. You pass in a query and a Result
- * set. When this Searcher is called with that query it will return
- * that result set.</p>
- *
- * <p>This supports multi-phase search.</p>
- *
- * <p>To avoid having to add type information for the fields, a quck hack is used to
- * support testing of attribute prefetching.
- * Any field in the configured hits which has a name starting by attribute
- * will be returned when attribute prefetch filling is requested.</p>
- *
- * @author bratseth
- * @deprecated use {@link com.yahoo.search.searchchain.testutil.DocumentSourceSearcher}
- */
-@SuppressWarnings({"rawtypes"})
-// TODO: Remove on Vespa 7
-@Deprecated // OK
-public class DocumentSourceSearcher extends Searcher {
-
- // as for the SuppressWarnings annotation above, we are inside
- // com.yahoo.prelude, this is old stuff, really no point firing off those
- // warnings here...
-
- private Result defaultFilledResult;
- private Map<Query, Result> completelyFilledResults = new HashMap<>();
- private Map<Query, Result> attributeFilledResults = new HashMap<>();
- private Map<Query, Result> unFilledResults = new HashMap<>();
-
- /** Time (in ms) at which the index of this searcher was last modified */
- long editionTimeStamp=0;
-
- private int queryCount;
-
- public DocumentSourceSearcher() {
- addDefaultResults();
- }
-
- /**
- * Adds a result which can be returned either as empty,
- * filled or attribute only filled later.
- * Summary fields starting by "a" are attributes, others are not.
- *
- * @return true when replacing an existing &lt;query, result&gt; pair.
- */
- public boolean addResultSet(Query query, Result fullResult) {
- Result emptyResult = new Result(query.clone());
- Result attributeResult = new Result(query.clone());
- emptyResult.setTotalHitCount(fullResult.getTotalHitCount());
- attributeResult.setTotalHitCount(fullResult.getTotalHitCount());
- int counter=0;
- for (Iterator i = fullResult.hits().deepIterator();i.hasNext();) {
- Hit fullHit = (Hit)i.next();
-
- Hit emptyHit = fullHit.clone();
- emptyHit.clearFields();
- emptyHit.setFillable();
- emptyHit.setRelevance(fullHit.getRelevance());
-
- Hit attributeHit = fullHit.clone();
- removePropertiesNotStartingByA(attributeHit);
- attributeHit.setFillable();
- attributeHit.setRelevance(fullHit.getRelevance());
- for (Object propertyKeyObject : fullHit.fields().keySet()) {
- String propertyKey=propertyKeyObject.toString();
- if (propertyKey.startsWith("attribute"))
- attributeHit.setField(propertyKey, fullHit.getField(propertyKey));
- }
- if (fullHit.getField(Hit.SDDOCNAME_FIELD)!=null)
- attributeHit.setField(Hit.SDDOCNAME_FIELD, fullHit.getField(Hit.SDDOCNAME_FIELD));
-
- // A simple summary lookup mechanism, similar to FastSearch's
- emptyHit.setField("summaryid", String.valueOf(counter));
- attributeHit.setField("summaryid", String.valueOf(counter));
- fullHit.setField("summaryid", String.valueOf(counter));
-
- counter++;
- emptyResult.hits().add(emptyHit);
- attributeResult.hits().add(attributeHit);
- }
- unFilledResults.put(getQueryKeyClone(query), emptyResult);
- attributeFilledResults.put(getQueryKeyClone(query), attributeResult);
- if (completelyFilledResults.put(getQueryKeyClone(query), fullResult.clone()) != null) {
- setEditionTimeStamp(System.currentTimeMillis());
- return true;
- }
- return false;
- }
-
- /**
- * Returns a query clone which has source, offset and hits set to null. This is used by access to
- * the maps using the query as key to achieve lookup independent of offset/hits value
- */
- private Query getQueryKeyClone(Query query) {
- Query key = query.clone();
- key.setWindow(0,0);
- key.getModel().setSources("");
- return key;
- }
-
- private void removePropertiesNotStartingByA(Hit hit) {
- List<String> toRemove=new java.util.ArrayList<>();
- for (Iterator i= ((Set) hit.fields().keySet()).iterator(); i.hasNext(); ) {
- String key=(String)i.next();
- if (!key.startsWith("a"))
- toRemove.add(key);
- }
- for (Iterator<String> i=toRemove.iterator(); i.hasNext(); ) {
- String propertyName=i.next();
- hit.removeField(propertyName);
- }
- }
-
- private void addDefaultResults() {
- Query q = new Query("?query=default");
- Result r = new Result(q);
- r.hits().add(new Hit("http://default-1.html"));
- r.hits().add(new Hit("http://default-2.html"));
- r.hits().add(new Hit("http://default-3.html"));
- r.hits().add(new Hit("http://default-4.html"));
- defaultFilledResult = r;
- addResultSet(q, r);
- }
-
- public long getEditionTimeStamp(){
- long myEditionTime;
- synchronized(this){
- myEditionTime=this.editionTimeStamp;
- }
- return myEditionTime;
- }
-
- public void setEditionTimeStamp(long editionTime) {
- synchronized(this){
- this.editionTimeStamp=editionTime;
- }
- }
-
- public Result search(com.yahoo.search.Query query, Execution execution) {
- queryCount++;
- Result r;
- r = unFilledResults.get(getQueryKeyClone(query));
- if (r == null) {
- r = defaultFilledResult.clone();
- } else {
- r = r.clone();
- }
- r.setQuery(query);
- r.hits().trim(query.getOffset(), query.getHits());
- return r;
- }
-
- @Override
- public void fill(com.yahoo.search.Result result, String summaryClass, Execution execution) {
- Result filledResult;
- if ("attributeprefetch".equals(summaryClass))
- filledResult=attributeFilledResults.get(getQueryKeyClone(result.getQuery()));
- else
- filledResult = completelyFilledResults.get(getQueryKeyClone(result.getQuery()));
-
- if (filledResult == null) {
- filledResult = defaultFilledResult;
- }
- fillHits(filledResult,result,summaryClass);
- }
-
- private void fillHits(Result source,Result target,String summaryClass) {
- for (Iterator hitsToFill= target.hits().deepIterator() ; hitsToFill.hasNext();) {
- Hit hitToFill = (Hit) hitsToFill.next();
- String summaryId= (String) hitToFill.getField("summaryid");
- if (summaryId==null) continue; // Can not fill this
- Hit filledHit = lookupBySummaryId(source,summaryId);
- if (filledHit==null)
- throw new RuntimeException("Can't fill hit with summaryid '" + summaryId + "', not present");
-
- for (Iterator props= filledHit.fieldIterator();props.hasNext();) {
- Map.Entry propertyEntry = (Map.Entry)props.next();
- hitToFill.setField(propertyEntry.getKey().toString(),
- propertyEntry.getValue());
- }
- hitToFill.setFilled(summaryClass);
- }
- target.analyzeHits();
- }
-
- private Hit lookupBySummaryId(Result result,String summaryId) {
- for (Iterator i= result.hits().deepIterator(); i.hasNext(); ) {
- Hit hit=(Hit)i.next();
- if (summaryId.equals(hit.getField("summaryid"))) {
- return hit;
- }
- }
- return null;
- }
-
- /**
- * Returns the number of queries made to this searcher since the last
- * reset. For testing - not reliable if multiple threads makes
- * queries simultaneously
- */
- public int getQueryCount() {
- return queryCount;
- }
-
- public void resetQueryCount() {
- queryCount=0;
- }
-
-}
diff --git a/container-search/src/main/java/com/yahoo/prelude/searcher/JuniperSearcher.java b/container-search/src/main/java/com/yahoo/prelude/searcher/JuniperSearcher.java
index 5c56379efc0..d11b8d86d29 100644
--- a/container-search/src/main/java/com/yahoo/prelude/searcher/JuniperSearcher.java
+++ b/container-search/src/main/java/com/yahoo/prelude/searcher/JuniperSearcher.java
@@ -77,10 +77,9 @@ public class JuniperSearcher extends Searcher {
@Override
public void fill(Result result, String summaryClass, Execution execution) {
- Result workResult = result;
- int worstCase = workResult.getHitCount();
+ int worstCase = result.getHitCount();
List<Hit> hits = new ArrayList<>(worstCase);
- for (Iterator<Hit> i = workResult.hits().deepIterator(); i.hasNext();) {
+ for (Iterator<Hit> i = result.hits().deepIterator(); i.hasNext();) {
Hit sniffHit = i.next();
if ( ! (sniffHit instanceof FastHit)) continue;
@@ -89,26 +88,26 @@ public class JuniperSearcher extends Searcher {
hits.add(hit);
}
- execution.fill(workResult, summaryClass);
- highlight(workResult.getQuery().getPresentation().getBolding(), hits.iterator(), summaryClass,
+ execution.fill(result, summaryClass);
+ highlight(result.getQuery().getPresentation().getBolding(), hits.iterator(), summaryClass,
execution.context().getIndexFacts().newSession(result.getQuery()));
}
private void highlight(boolean bolding, Iterator<Hit> hitsToHighlight,
String summaryClass, IndexFacts.Session indexFacts) {
while (hitsToHighlight.hasNext()) {
- Hit sniffHit = hitsToHighlight.next();
- if ( ! (sniffHit instanceof FastHit)) continue;
+ Hit hit = hitsToHighlight.next();
+ if ( ! (hit instanceof FastHit)) continue;
- FastHit hit = (FastHit) sniffHit;
- if (summaryClass != null && ! hit.isFilled(summaryClass)) continue;
+ FastHit fastHit = (FastHit) hit;
+ if (summaryClass != null && ! fastHit.isFilled(summaryClass)) continue;
- Object searchDefinitionField = hit.getField(MAGIC_FIELD);
+ Object searchDefinitionField = fastHit.getField(MAGIC_FIELD);
if (searchDefinitionField == null) continue;
for (Index index : indexFacts.getIndexes(searchDefinitionField.toString())) {
if (index.getDynamicSummary() || index.getHighlightSummary()) {
- HitField fieldValue = hit.buildHitField(index.getName(), true, true);
+ HitField fieldValue = fastHit.buildHitField(index.getName(), true);
if (fieldValue != null)
insertTags(fieldValue, bolding, index.getDynamicSummary());
}
@@ -116,9 +115,9 @@ public class JuniperSearcher extends Searcher {
}
}
- private void insertTags(HitField oldProperty, boolean bolding, boolean dynteaser) {
+ private void insertTags(HitField field, boolean bolding, boolean dynteaser) {
boolean insideHighlight = false;
- for (ListIterator<FieldPart> i = oldProperty.listIterator(); i.hasNext();) {
+ for (ListIterator<FieldPart> i = field.listIterator(); i.hasNext();) {
FieldPart f = i.next();
if (f instanceof SeparatorFieldPart)
setSeparatorString(bolding, (SeparatorFieldPart) f);
@@ -138,8 +137,7 @@ public class JuniperSearcher extends Searcher {
break;
case RAW_SEPARATOR_CHAR:
newFieldParts = initFieldParts(newFieldParts);
- addSeparator(bolding, dynteaser, f, toQuote, newFieldParts,
- previous, j);
+ addSeparator(bolding, dynteaser, f, toQuote, newFieldParts, previous, j);
previous = j + 1;
break;
default:
diff --git a/container-search/src/main/java/com/yahoo/prelude/searcher/QuerySnapshotSearcher.java b/container-search/src/main/java/com/yahoo/prelude/searcher/QuerySnapshotSearcher.java
deleted file mode 100644
index 4edb907d337..00000000000
--- a/container-search/src/main/java/com/yahoo/prelude/searcher/QuerySnapshotSearcher.java
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-package com.yahoo.prelude.searcher;
-
-import com.yahoo.search.result.Hit;
-import com.yahoo.search.result.Relevance;
-import com.yahoo.search.Query;
-import com.yahoo.search.Result;
-import com.yahoo.search.Searcher;
-import com.yahoo.search.searchchain.Execution;
-
-/**
- * Save the query in the incoming state to a meta hit in the result.
- *
- * @author Steinar Knutsen
- * @deprecated do not use
- */
-// TODO: Remove on Vespa 7
-@Deprecated // OK
-public class QuerySnapshotSearcher extends Searcher {
-
- public Result search(Query query, Execution execution) {
- Query q = query.clone();
- Result r = execution.search(query);
- Hit h = new Hit("meta:querysnapshot", new Relevance(Double.POSITIVE_INFINITY));
- h.setMeta(true);
- h.setField("query", q);
- r.hits().add(h);
- return r;
- }
-
-}
diff --git a/container-search/src/main/java/com/yahoo/prelude/searcher/QueryValidatingSearcher.java b/container-search/src/main/java/com/yahoo/prelude/searcher/QueryValidatingSearcher.java
deleted file mode 100644
index fd155354d1c..00000000000
--- a/container-search/src/main/java/com/yahoo/prelude/searcher/QueryValidatingSearcher.java
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-package com.yahoo.prelude.searcher;
-
-import com.yahoo.search.result.ErrorMessage;
-import com.yahoo.search.Query;
-import com.yahoo.search.Result;
-import com.yahoo.search.Searcher;
-import com.yahoo.search.searchchain.Execution;
-
-/**
- * Ensures hits is 1000 or less and offset is 1000 or less.
- *
- * @author Steinar Knutsen
- * @deprecated do not use
- */
-// TODO: Remove on Vespa 7
-@Deprecated // OK
-public class QueryValidatingSearcher extends Searcher {
-
- public Result search(Query query, Execution execution) {
- if (query.getHits() > 1000) {
- Result result = new Result(query);
- ErrorMessage error
- = ErrorMessage.createInvalidQueryParameter("Too many hits (more than 1000) requested.");
- result.hits().addError(error);
- return result;
- }
- if (query.getOffset() > 1000) {
- Result result = new Result(query);
- ErrorMessage error
- = ErrorMessage.createInvalidQueryParameter("Offset too high (above 1000).");
- result.hits().addError(error);
- return result;
- }
- return execution.search(query);
- }
-
-}
diff --git a/container-search/src/main/java/com/yahoo/prelude/semantics/SemanticSearcher.java b/container-search/src/main/java/com/yahoo/prelude/semantics/SemanticSearcher.java
index 89849f98461..4d46107726e 100644
--- a/container-search/src/main/java/com/yahoo/prelude/semantics/SemanticSearcher.java
+++ b/container-search/src/main/java/com/yahoo/prelude/semantics/SemanticSearcher.java
@@ -15,7 +15,6 @@ import com.yahoo.search.searchchain.PhaseNames;
import java.util.*;
-import static com.yahoo.prelude.querytransform.IndexCombinatorSearcher.MIXED_RECALL_REWRITE;
import static com.yahoo.prelude.querytransform.StemmingSearcher.STEMMING;
/**
@@ -24,7 +23,7 @@ import static com.yahoo.prelude.querytransform.StemmingSearcher.STEMMING;
* @author bratseth
*/
@After(PhaseNames.RAW_QUERY)
-@Before({PhaseNames.TRANSFORMED_QUERY, STEMMING, MIXED_RECALL_REWRITE})
+@Before({PhaseNames.TRANSFORMED_QUERY, STEMMING})
public class SemanticSearcher extends Searcher {
private static final CompoundName rulesRulebase=new CompoundName("rules.rulebase");
diff --git a/container-search/src/main/java/com/yahoo/prelude/statistics/StatisticsSearcher.java b/container-search/src/main/java/com/yahoo/prelude/statistics/StatisticsSearcher.java
index beb79acb893..3606e01ffe5 100644
--- a/container-search/src/main/java/com/yahoo/prelude/statistics/StatisticsSearcher.java
+++ b/container-search/src/main/java/com/yahoo/prelude/statistics/StatisticsSearcher.java
@@ -3,7 +3,6 @@ package com.yahoo.prelude.statistics;
import com.yahoo.component.chain.dependencies.Before;
import com.yahoo.concurrent.CopyOnWriteHashMap;
-import com.yahoo.container.Server;
import com.yahoo.container.protect.Error;
import com.yahoo.jdisc.Metric;
import com.yahoo.log.LogLevel;
@@ -18,9 +17,7 @@ import com.yahoo.search.result.ErrorHit;
import com.yahoo.search.result.ErrorMessage;
import com.yahoo.search.searchchain.Execution;
import com.yahoo.search.searchchain.PhaseNames;
-import com.yahoo.statistics.Callback;
import com.yahoo.statistics.Counter;
-import com.yahoo.statistics.Handle;
import com.yahoo.statistics.Value;
import java.util.HashMap;
diff --git a/container-search/src/main/java/com/yahoo/prelude/templates/Context.java b/container-search/src/main/java/com/yahoo/prelude/templates/Context.java
deleted file mode 100644
index 7662ca832f9..00000000000
--- a/container-search/src/main/java/com/yahoo/prelude/templates/Context.java
+++ /dev/null
@@ -1,116 +0,0 @@
-// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-package com.yahoo.prelude.templates;
-
-import java.util.Collection;
-
-import com.yahoo.text.XML;
-
-/**
- * A set of variable bindings for template rendering
- *
- * @author bratseth
- * @deprecated use a Renderer instead
- */
-@SuppressWarnings("deprecation")
-// TODO: Remove on Vespa 7
-@Deprecated // OK (But wait for deprecated handlers in vespaclient-container-plugin to be removed)
-public abstract class Context {
-
- private boolean xmlEscape = true;
-
- // These may be wrapped in an object if it gets unruly like this...
- private String boldOpenTag;
- private String boldCloseTag;
- private String separatorTag;
-
- private boolean utf8Output = false;
-
- //prevent sub-classing outside of this package.
- Context() {}
-
- // set|getXmlEscape no longer final on cause of HitContext subclassing _and_ wrapping Context
- /** Sets whether this context should xml-escape returned values */
- public void setXmlEscape(boolean xmlEscape) { this.xmlEscape=xmlEscape; }
-
- /** Returns whether this context xml-escapes returned values. Default is true */
- public boolean getXmlEscape() { return xmlEscape; }
-
- /**
- * Makes a <b>secondary</b> binding
- *
- * @return the old value bound to this key, or null it the key was previously unbound
- */
- public abstract Object put(String key,Object value);
-
- /**
- * <p>Returns a value by looking it up in the primary,
- * and thereafter in secondary sources.</p>
- *
- * <p>If xml escaping is on and this is a string, xml attribute escaping is done
- * </p>
- */
- abstract public Object get(String key);
-
- /**
- * Removes a <b>secondary</b> binding
- *
- * @return the removed value, or null if it wasn't bound
- */
- public abstract Object remove(Object key);
-
-
- // These three may be collapsed to one method
- public void setBoldOpenTag(String boldOpenTag) {
- this.boldOpenTag = boldOpenTag;
- }
- public void setBoldCloseTag(String boldCloseTag) {
- this.boldCloseTag = boldCloseTag;
- }
- public void setSeparatorTag(String separatorTag) {
- this.separatorTag = separatorTag;
- }
-
-
- protected Object normalizeValue(Object value) {
- if (value == null) {
- return "";
- } else if (xmlEscape && value instanceof String) {
- return XML.xmlEscape((String) value, true, null);
- } else {
- return value;
- }
- }
-
- public String getBoldOpenTag() {
- return boldOpenTag;
- }
-
- public String getBoldCloseTag() {
- return boldCloseTag;
- }
-
- public String getSeparatorTag() {
- return separatorTag;
- }
-
- public abstract Collection<? extends Object> getKeys();
-
- /**
- * Used by the template to decide whether to use UTF-8 optimizations.
- *
- * @return whether the result encoding is UTF-8
- */
- public boolean isUtf8Output() {
- return utf8Output;
- }
-
- /**
- * Used by the template to decide whether to use UTF-8 optimizations.
- * TODO: TVT: Make this package private again
- * @param utf8Output whether the output encoding is UTF-8
- */
- public void setUtf8Output(boolean utf8Output) {
- this.utf8Output = utf8Output;
- }
-
-}
diff --git a/container-search/src/main/java/com/yahoo/prelude/templates/DefaultTemplateSet.java b/container-search/src/main/java/com/yahoo/prelude/templates/DefaultTemplateSet.java
deleted file mode 100644
index 4d6406fe00d..00000000000
--- a/container-search/src/main/java/com/yahoo/prelude/templates/DefaultTemplateSet.java
+++ /dev/null
@@ -1,299 +0,0 @@
-// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-package com.yahoo.prelude.templates;
-
-import com.yahoo.concurrent.CopyOnWriteHashMap;
-import com.yahoo.io.ByteWriter;
-import com.yahoo.net.URI;
-import com.yahoo.prelude.fastsearch.FastHit;
-import com.yahoo.prelude.hitfield.HitField;
-import com.yahoo.prelude.hitfield.JSONString;
-import com.yahoo.prelude.hitfield.XMLString;
-import com.yahoo.search.Result;
-import com.yahoo.search.grouping.result.HitRenderer;
-import com.yahoo.search.result.*;
-import com.yahoo.text.Utf8String;
-import com.yahoo.text.XML;
-import com.yahoo.text.XMLWriter;
-
-import java.io.IOException;
-import java.io.Writer;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.stream.Collectors;
-
-/**
- * <p>A template set which provides XML rendering of results and hits.</p>
- *
- * <p>This can be extended to create custom programmatic templates.
- * Create a subclass which has static inner classes extending DefaultTemplate for the templates
- * you wish to override and call the set method for those templates in the subclass template set
- * constructor. Some of the default templates contained utility functions, and can be overridden
- * in place of DefaultTemplate to gain access to these. See TiledTemplateSet for an example.</p>
- *
- * @author bratseth
- * @deprecated use JsonRenderer instead
- */
-@SuppressWarnings("deprecation")
-// TODO: Remove on Vespa 7
-@Deprecated // OK (But wait for deprecated handlers in vespaclient-container-plugin to be removed)
-public class DefaultTemplateSet extends UserTemplate<XMLWriter> {
-
- private static final Utf8String RESULT = new Utf8String("result");
- private static final Utf8String GROUP = new Utf8String("group");
- private static final Utf8String ID = new Utf8String("id");
- private static final Utf8String FIELD = new Utf8String("field");
- private static final Utf8String HIT = new Utf8String("hit");
- private static final Utf8String ERROR = new Utf8String("error");
- private static final Utf8String TOTAL_HIT_COUNT = new Utf8String("total-hit-count");
- private static final Utf8String QUERY_TIME = new Utf8String("querytime");
- private static final Utf8String SUMMARY_FETCH_TIME = new Utf8String("summaryfetchtime");
- private static final Utf8String SEARCH_TIME = new Utf8String("searchtime");
- private static final Utf8String NAME = new Utf8String("name");
- private static final Utf8String CODE = new Utf8String("code");
- private static final Utf8String COVERAGE_DOCS = new Utf8String("coverage-docs");
- private static final Utf8String COVERAGE_NODES = new Utf8String("coverage-nodes");
- private static final Utf8String COVERAGE_FULL = new Utf8String("coverage-full");
- private static final Utf8String COVERAGE = new Utf8String("coverage");
- private static final Utf8String RESULTS_FULL = new Utf8String("results-full");
- private static final Utf8String RESULTS = new Utf8String("results");
- private static final Utf8String TYPE = new Utf8String("type");
- private static final Utf8String RELEVANCY = new Utf8String("relevancy");
- private static final Utf8String SOURCE = new Utf8String("source");
-
- private final CopyOnWriteHashMap<String, Utf8String> fieldNameMap = new CopyOnWriteHashMap<>();
-
-
- /**
- * Create a template set with a name. This will be initialized with the default templates -
- * use the set methods from the subclass constructor to override any of these with other template classes.
- */
- protected DefaultTemplateSet(String name) {
- super(name,
- DEFAULT_MIMETYPE,
- DEFAULT_ENCODING
- );
- }
-
- public DefaultTemplateSet() {
- this("default");
- }
-
- /** Uses an XML writer in this template */
- @Override
- public XMLWriter wrapWriter(Writer writer) {
- return XMLWriter.from(writer, 10, -1);
- }
-
- @Override
- public void header(Context context, XMLWriter writer) throws IOException {
- Result result=(Result)context.get("result");
- // TODO: move setting this to Result
- context.setUtf8Output("utf-8".equalsIgnoreCase(getRequestedEncoding(result.getQuery())));
- writer.xmlHeader(getRequestedEncoding(result.getQuery()));
- writer.openTag(RESULT).attribute(TOTAL_HIT_COUNT,String.valueOf(result.getTotalHitCount()));
- renderCoverageAttributes(result.getCoverage(false), writer);
- renderTime(writer, result);
- writer.closeStartTag();
- }
-
- private void renderTime(final XMLWriter writer, final Result result) {
- if (!result.getQuery().getPresentation().getTiming()) {
- return;
- }
-
- final String threeDecimals = "%.3f";
- final double milli = .001d;
- final long now = System.currentTimeMillis();
- final long searchTime = now - result.getElapsedTime().first();
- final double searchSeconds = ((double) searchTime) * milli;
-
- if (result.getElapsedTime().firstFill() != 0L) {
- final long queryTime = result.getElapsedTime().weightedSearchTime();
- final long summaryFetchTime = result.getElapsedTime().weightedFillTime();
- final double querySeconds = ((double) queryTime) * milli;
- final double summarySeconds = ((double) summaryFetchTime) * milli;
- writer.attribute(QUERY_TIME, String.format(threeDecimals, querySeconds));
- writer.attribute(SUMMARY_FETCH_TIME, String.format(threeDecimals, summarySeconds));
- }
- writer.attribute(SEARCH_TIME, String.format(threeDecimals, searchSeconds));
- }
-
- @Override
- public void footer(Context context, XMLWriter writer) throws IOException {
- writer.closeTag();
- }
-
- @Override
- /**
- * Renders the header of a hit.<br/>
- * Post-condition: The hit tag is open in this XML writer
- */
- public void hit(Context context, XMLWriter writer) throws IOException {
- Hit hit=(Hit)context.get("hit");
-
- if (hit instanceof HitGroup) {
- renderHitGroup((HitGroup) hit, context, writer);
- } else {
- writer.openTag(HIT);
- renderHitAttributes(hit,writer);
- writer.closeStartTag();
- renderHitFields(context, hit, writer);
- }
- }
-
-
- @Override
- /**
- * Renders the footer of a hit.
- *
- * Pre-condition: The hit tag is open in this XML writer.<br/>
- * Post-condition: The hit tag is closed
- */
- public void hitFooter(Context context, XMLWriter writer) throws IOException {
- writer.closeTag();
- }
-
- @Override
- public void error(Context context, XMLWriter writer) {
- ErrorMessage error=((Result)context.get("result")).hits().getError();
- writer.openTag(ERROR).attribute(CODE,error.getCode()).content(error.getMessage(),false).closeTag();
- }
-
- @Override
- public void noHits(Context context, XMLWriter writer) {
- // no hits, do nothing :)
- }
-
- protected static void renderCoverageAttributes(Coverage coverage, XMLWriter writer) {
- if (coverage == null) return;
- writer.attribute(COVERAGE_DOCS,coverage.getDocs());
- writer.attribute(COVERAGE_NODES,coverage.getNodes());
- writer.attribute(COVERAGE_FULL,coverage.getFull());
- writer.attribute(COVERAGE,coverage.getResultPercentage());
- writer.attribute(RESULTS_FULL,coverage.getFullResultSets());
- writer.attribute(RESULTS,coverage.getResultSets());
- }
-
- /**
- * Writes a hit's default attributes like 'type', 'source', 'relevancy'.
- */
- protected void renderHitAttributes(Hit hit, XMLWriter writer) throws IOException {
- writer.attribute(TYPE, hit.types().stream().collect(Collectors.joining(" ")));
- if (hit.getRelevance() != null) {
- writer.attribute(RELEVANCY, hit.getRelevance().toString());
- }
- writer.attribute(SOURCE, hit.getSource());
- }
-
- /** Opens (but does not close) the group hit tag */
- protected void renderHitGroup(HitGroup hit, Context context, XMLWriter writer) throws IOException {
- if (HitRenderer.renderHeader(hit, writer)) {
- // empty
- } else if (hit.types().contains("grouphit")) {
- // TODO Keep this?
- renderHitGroupOfTypeGroupHit(context, hit, writer);
- } else {
- renderGroup(hit, writer);
- }
- }
-
- /**
- * Renders a hit group.
- */
- protected void renderGroup(HitGroup hit, XMLWriter writer) throws IOException {
- writer.openTag(GROUP);
- renderHitAttributes(hit, writer);
- writer.closeStartTag();
- }
-
- // Can't name this renderGroupHit as GroupHit is a class having nothing to do with HitGroup.
- // Confused yet? Good!
- protected void renderHitGroupOfTypeGroupHit(Context context, HitGroup hit, XMLWriter writer) throws IOException {
- writer.openTag(HIT);
- renderHitAttributes(hit, writer);
- renderId(hit.getId(), writer);
- writer.closeStartTag();
- }
-
-
- protected void renderId(URI uri, XMLWriter writer) {
- if (uri != null) {
- writer.openTag(ID).content(uri.stringValue(),false).closeTag();
- }
- }
-
- /**
- * Renders all fields of a hit.
- * Simply calls {@link #renderField(Context, Hit, java.util.Map.Entry, XMLWriter)} for every field.
- */
- protected void renderHitFields(Context context, Hit hit, XMLWriter writer) throws IOException {
- renderSyntheticRelevancyField(hit, writer);
- for (Iterator<Map.Entry<String, Object>> it = hit.fieldIterator(); it.hasNext(); ) {
- renderField(context, hit, it.next(), writer);
- }
- }
-
- private void renderSyntheticRelevancyField(Hit hit, XMLWriter writer) {
- final String relevancyFieldName = "relevancy";
- final Relevance relevance = hit.getRelevance();
-
- if (shouldRenderField(hit, relevancyFieldName) && relevance != null) {
- renderSimpleField(relevancyFieldName, relevance, writer);
- }
- }
-
- protected void renderField(Context context, Hit hit, Map.Entry<String, Object> entry, XMLWriter writer) throws IOException {
- String fieldName = entry.getKey();
-
- if (!shouldRenderField(hit, fieldName)) return;
- if (fieldName.startsWith("$")) return; // Don't render fields that start with $ // TODO: Move to should render
-
- writeOpenFieldElement(fieldName, writer);
- renderFieldContent(context, hit, fieldName, writer);
- writeCloseFieldElement(writer);
- }
-
- private void writeOpenFieldElement(String fieldName, XMLWriter writer) {
- Utf8String utf8 = fieldNameMap.get(fieldName);
- if (utf8 == null) {
- utf8 = new Utf8String(fieldName);
- fieldNameMap.put(fieldName, utf8);
- }
- writer.openTag(FIELD).attribute(NAME, utf8);
- writer.closeStartTag();
- }
-
- private void writeCloseFieldElement(XMLWriter writer) {
- writer.closeTag();
- }
-
- protected void renderFieldContent(Context context, Hit hit, String name, XMLWriter writer) {
- writer.escapedContent(asXML(hit.getField(name)), false);
- }
-
- private String asXML(Object value) {
- if (value == null)
- return "(null)";
- else if (value instanceof HitField)
- return ((HitField)value).quotedContent(false);
- else if (value instanceof StructuredData || value instanceof XMLString || value instanceof JSONString)
- return value.toString();
- else
- return XML.xmlEscape(value.toString(), false, '\u001f');
- }
-
- private void renderSimpleField(String fieldName, Object fieldValue, XMLWriter writer) {
- writeOpenFieldElement(fieldName, writer);
- writer.content(fieldValue.toString(),false);
- writeCloseFieldElement(writer);
- }
-
- /** Returns whether a field should be rendered. This default implementation always returns true */
- protected boolean shouldRenderField(Hit hit, String fieldName) {
- // skip depending on hit type
- return true;
- }
-
-
-
-}
diff --git a/container-search/src/main/java/com/yahoo/prelude/templates/FormattingOptions.java b/container-search/src/main/java/com/yahoo/prelude/templates/FormattingOptions.java
deleted file mode 100644
index 1f724aba112..00000000000
--- a/container-search/src/main/java/com/yahoo/prelude/templates/FormattingOptions.java
+++ /dev/null
@@ -1,193 +0,0 @@
-// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-package com.yahoo.prelude.templates;
-
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedHashMap;
-import java.util.LinkedHashSet;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * Defines formatting options used with special kinds of hits.
- *
- * @author laboisse
- * @deprecated use a Renderer instead
- */
-@SuppressWarnings("deprecation")
-// TODO: Remove on Vespa 7
-@Deprecated // OK (But wait for deprecated handlers in vespaclient-container-plugin to be removed)
-public class FormattingOptions {
-
- public static final String DEFAULT_TYPE_ATTRIBUTE_NAME = "type";
-
- /**
- * A structure that defines the tag name and attribute name for a field
- * that sould be formatted as a field with a subtype.
- * @author laboisse
- *
- */
- static class SubtypeField {
- String tagName;
- String attributeName;
- String attributeValue;
- }
-
- static class SubtypeFieldWithPrefix extends SubtypeField {
-
- /* Note: attributeValue should always be null for instances of this class */
-
- int prefixLength;
- }
-
- private Map<String, String> fieldsAsAttributes = new LinkedHashMap<>();
-
- private Map<String, SubtypeField> fieldsWithSubtypes = new LinkedHashMap<>();
- private Map<String, SubtypeFieldWithPrefix> prefixedFieldsWithSubtypes = new LinkedHashMap<>();
-
- private Set<String> fieldsNotRendered = new LinkedHashSet<>();
- private Set<String> fieldsRendered = new LinkedHashSet<>();
-
- /**
- * Tells to format a field as an attribute of the hit's tag.
- *
- * For instance, field 'query-latency' could be rendered as an attribute 'latency' by
- * invoking {@code formatFieldAsAttribute("query-latency", "latency")}.
- *
- * Output would be:
- * <pre>
- * &lt;hit latency="100"&gt;&lt;/hit&gt;
- * </pre>
- * instead of:
- * <pre>
- * &lt;hit&gt;&lt;latency&gt;100&lt;/latency&gt;&lt;/hit&gt;
- * </pre>
- */
- public void formatFieldAsAttribute(String fieldName, String attributeName) {
- fieldsAsAttributes.put(fieldName, attributeName);
- }
-
- public Set<Map.Entry<String, String>> fieldsAsAttributes() {
- return Collections.unmodifiableSet(this.fieldsAsAttributes.entrySet());
- }
-
- public String getAttributeName(String fieldName) {
- return this.fieldsAsAttributes.get(fieldName);
- }
-
- /**
- * Tells to format a field using a subtype. A subtype is used when there is kind of a grouping
- * for a set of fields.
- *
- * For instance, fields 'latency-connect', 'latency-finish' all belong to the same 'latency' logical group.
- * So invoking {@code formatFieldWithSubtype("latency-connect", "latency", "type", "connect"},
- * {@code formatFieldWithSubtype("latency-finish", "latency", "type", "connect"} and so on,
- * allows to have a common 'latency' tag name for all fields of the same kind.
- * Note that it does no collapsing on tags.
- *
- * Output would be:
- * <pre>
- * &lt;latency type="connect"&gt;50&lt;/latency&gt;
- * &lt;latency type="finish"&gt;250&lt;/latency&gt;
- * </pre>
- * Instead of:
- * <pre>
- * &lt;hit&gt;
- * &lt;latency-connect&gt;50&lt;/latency-connect&gt;
- * &lt;latency-finish&gt;50&lt;/latency-finish&gt;
- * </pre>
- */
- public void formatFieldWithSubtype(String fieldName, String tagName, String typeAttributeName, String typeAttributeValue) {
- SubtypeField names = new SubtypeField();
- names.attributeName = typeAttributeName;
- names.attributeValue = typeAttributeValue;
- names.tagName = tagName;
- fieldsWithSubtypes.put(fieldName, names);
- }
-
- public SubtypeField getSubtype(String fieldName) {
- return this.fieldsWithSubtypes.get(fieldName);
- }
-
- /**
- * Same as {@link #formatFieldWithSubtype(String, String, String, String)} except that fields
- * are selected based on the beginning of their name and the type attribute value is deduced
- * from the rest of their name. So this may select many fields instead of only one.
- * Invoking {@code formatFieldWithSubtype("latency-", "latency", "type")} only once allows to have a common 'latency'
- * tag name for all fields that start with 'latency-'. Type attribute value will be 'start' for field 'latency-start'.
- * Note that it does no collapsing on tags.
- *
- * This is mostly used when you don't know all field names ahead.
- *
- * Output would be:
- * <pre>
- * &lt;latency type="connect"&gt;50&lt;/latency&gt;
- * &lt;latency type="finish"&gt;250&lt;/latency&gt;
- * </pre>
- * Instead of:
- * <pre>
- * &lt;hit&gt;
- * &lt;latency-connect&gt;50&lt;/latency-connect&gt;
- * &lt;latency-finish&gt;50&lt;/latency-finish&gt;
- * </pre>
- *
- * Note: don't use this with prefixes that start with a common substring (e.g. 'http', 'http_proxy'), I can tell you it just won't work.
- */
- public void formatFieldWithSubtype(String fieldNamePrefix, String tagName, String typeAttributeName) {
- SubtypeFieldWithPrefix names = new SubtypeFieldWithPrefix();
- names.attributeName = typeAttributeName;
- names.tagName = tagName;
- names.prefixLength = fieldNamePrefix.length();
- prefixedFieldsWithSubtypes.put(fieldNamePrefix, names);
- }
-
- public SubtypeFieldWithPrefix getSubtypeWithPrefix(String fieldName) {
- for(Map.Entry<String, SubtypeFieldWithPrefix> e : this.prefixedFieldsWithSubtypes.entrySet()) {
- if(fieldName.startsWith(e.getKey()))
- return e.getValue();
- }
- return null;
- }
-
- /**
- * Tells whether a field should be rendered.
- *
- * @see #setFieldNotToRender(String)
- * @see #setFieldToRender(String)
- */
- public boolean shouldRenderField(String fieldName) {
- if(fieldName == null)
- return false;
- if (fieldName.startsWith("$")) {
- return false;
- }
- if(!this.fieldsRendered.isEmpty())
- return this.fieldsRendered.contains(fieldName);
- return !this.fieldsNotRendered.contains(fieldName);
- }
-
- /**
- * Tells a field should be rendered.
- *
- * <p>
- * Note: if at least one field is set to render, then only
- * these fields should be rendered. Use {@link #setFieldNotToRender(String)}
- * to only exclude specific fields.
- */
- public void setFieldToRender(String fieldName) {
- this.fieldsRendered.add(fieldName);
- }
-
- /**
- * Tells a field should not be rendered.
- *
- * <p>
- * Note: all other fields should be rendered. Use {@link #setFieldToRender(String)}
- * to only include specific fields.
- */
- public void setFieldNotToRender(String fieldName) {
- this.fieldsNotRendered.add(fieldName);
- }
-
-}
diff --git a/container-search/src/main/java/com/yahoo/prelude/templates/GenericTemplateSet.java b/container-search/src/main/java/com/yahoo/prelude/templates/GenericTemplateSet.java
deleted file mode 100644
index 95875d0dd1f..00000000000
--- a/container-search/src/main/java/com/yahoo/prelude/templates/GenericTemplateSet.java
+++ /dev/null
@@ -1,158 +0,0 @@
-// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-package com.yahoo.prelude.templates;
-
-import com.yahoo.protect.Validator;
-import com.yahoo.search.Query;
-
-import java.io.Writer;
-import java.util.HashMap;
-import java.util.LinkedHashMap;
-import java.util.Properties;
-
-/**
- * Superclass of a set of templates for rendering (serializing) results
- *
- * @deprecated use a renderer instead
- */
-// TODO: Remove on Vespa 7
-@Deprecated // OK (But wait for deprecated handlers in vespaclient-container-plugin to be removed)
-public class GenericTemplateSet {
-
- public static final String DEFAULT_MIMETYPE = "text/xml";
- public static final String DEFAULT_ENCODING = "utf-8";
-
- /** Templates */
- private HashMap<String, Template<? extends Writer>> templates;
-
- /** The text MIME subtype this template returns, xml, plain or html */
- private String mimeType;
-
- /** The charset encoding this template should have */
- private String encoding;
-
- private String boldOpenTag = null;
- private String boldCloseTag = null;
- private String separatorTag = null;
-
- /**
- * Document summary class for this template
- */
- private String summaryClass = null;
-
- /**
- * The unique name of this template set
- */
- private final String name;
-
- /**
- * Creates a template set containing no templates
- */
- public GenericTemplateSet(String name, String mimeType, String encoding) {
- this.mimeType = mimeType;
- this.encoding = encoding;
- this.name = name;
-
- templates = new LinkedHashMap<>();
- }
-
-
- public String getName() {
- return name;
- }
-
- /**
- * Returns the text MIME
- */
- public String getMimeType() { return mimeType; }
-
- /**
- * Returns the text encoding
- */
- public String getEncoding() { return encoding; }
-
- /** Returns the encoding of the query, or the encoding given by the template if none is set */
- public final String getRequestedEncoding(Query query) {
- String encoding = query.getModel().getEncoding();
- if (encoding != null) return encoding;
- return getEncoding();
- }
-
- /**
- * Returns the selected template
- *
- * @return the template to use, never null
- */
- public Template<? extends Writer> getTemplate(String templateName) {
- return templates.get(templateName);
- }
-
- /**
- * Sets the selected template
- *
- * @throws NullPointerException if the given template is null
- */
- public void setTemplate(String templateName, Template<? extends Writer> template) {
- templates.put(templateName,template);
- }
-
- /**
- * Sets the selected template
- *
- * @throws NullPointerException if the given template is null
- */
- public void setTemplateNotNull(String templateName, Template<? extends Writer> template) {
- Validator.ensureNotNull("Template "+templateName,template);
- templates.put(templateName,template);
- }
-
-
- /**
- * Sets the highligting marks for this template
- *
- * @param start the highlingting start mark
- * @param end the highlingting end mark
- * @param sep the highlingting separator mark
- */
- public void setHighlightTags(String start, String end, String sep) {
- boldOpenTag = start;
- boldCloseTag = end;
- separatorTag = sep;
- }
-
- // may return null
- public String getBoldOpenTag() {
- return boldOpenTag;
- }
-
- // may return null
- public String getBoldCloseTag() {
- return boldCloseTag;
- }
-
- // may return null
- public String getSeparatorTag() {
- return separatorTag;
- }
-
-
- /**
- * Set the default summary class to use with this template.
- */
- public void setSummaryClass(String summaryClass) {
- this.summaryClass = summaryClass;
- }
-
- /**
- * Type safe accessor to get the default document summary class for this
- * template set. This is also here to insulate the rest of the code
- * against changes in the naming of the properties in the property file.
- */
- public String getSummaryClass() {
- if (summaryClass != null && ! summaryClass.isEmpty()) {
- return summaryClass;
- } else {
- return null;
- }
- }
-
-}
diff --git a/container-search/src/main/java/com/yahoo/prelude/templates/HitContext.java b/container-search/src/main/java/com/yahoo/prelude/templates/HitContext.java
deleted file mode 100644
index 5ef28d6f6c6..00000000000
--- a/container-search/src/main/java/com/yahoo/prelude/templates/HitContext.java
+++ /dev/null
@@ -1,147 +0,0 @@
-// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-package com.yahoo.prelude.templates;
-
-import com.yahoo.prelude.hitfield.HitField;
-import com.yahoo.prelude.hitfield.JSONString;
-import com.yahoo.prelude.hitfield.XMLString;
-import com.yahoo.search.result.Hit;
-import com.yahoo.search.result.StructuredData;
-import com.yahoo.text.XML;
-
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.Set;
-
-/**
- * A context providing all the fields of a hit, and falls back to MapContext behavior for all other keys.
- *
- * @author Tony Vaagenes
- * @deprecated use a Renderer instead
- */
-@SuppressWarnings("deprecation")
-// TODO: Remove on Vespa 7
-@Deprecated // OK (But wait for deprecated handlers in vespaclient-container-plugin to be removed)
-public class HitContext extends Context {
-
- private final Hit hit;
- private final Context fallbackContext;
-
- public HitContext(Hit hit, Context fallbackContext) {
- this.hit = hit;
- this.fallbackContext = fallbackContext;
- }
-
- @Override
- public Object put(String key, Object value) {
- return fallbackContext.put(key, value);
- }
-
- @Override
- public Object get(String key) {
- Object value = normalizedHitProperty(key);
- return value != null ?
- value :
- fallbackContext.get(key);
- }
-
- @Override
- public Object remove(Object key) {
- return fallbackContext.remove(key);
- }
-
- @Override
- public Collection<? extends Object> getKeys() {
- Set<Object> keys = new HashSet<>(fallbackContext.getKeys());
- keys.addAll(hit.fieldKeys());
- return keys;
- }
-
- @Override
- public void setBoldOpenTag(String boldOpenTag) {
- fallbackContext.setBoldOpenTag(boldOpenTag);
- }
-
- @Override
- public void setBoldCloseTag(String boldCloseTag) {
- fallbackContext.setBoldCloseTag(boldCloseTag);
- }
-
- @Override
- public void setSeparatorTag(String separatorTag) {
- fallbackContext.setSeparatorTag(separatorTag);
- }
-
- @Override
- public String getBoldOpenTag() {
- return fallbackContext.getBoldOpenTag();
- }
-
- @Override
- public String getBoldCloseTag() {
- return fallbackContext.getBoldCloseTag();
- }
-
- @Override
- public String getSeparatorTag() {
- return fallbackContext.getSeparatorTag();
- }
-
- @Override
- //TVT: TODO: Make this package private again.
- public boolean isUtf8Output() {
- return fallbackContext.isUtf8Output();
- }
-
- @Override
- //TODO: TVT: make this package private again
- public void setUtf8Output(boolean utf8Output) {
- fallbackContext.setUtf8Output(utf8Output);
- }
-
- @Override
- public void setXmlEscape(boolean xmlEscape) {
- fallbackContext.setXmlEscape(xmlEscape);
- }
-
- @Override
- public boolean getXmlEscape() {
- return fallbackContext.getXmlEscape();
- }
-
- @Override
- protected Object normalizeValue(Object value) {
- return fallbackContext.normalizeValue(value);
- }
-
- private Object normalizedHitProperty(String key) {
- Object value = hit.getField(key);
- return value == null ?
- null :
- normalizeHitFieldValue(value);
- }
-
- private Object normalizeHitFieldValue(Object value) {
- if (value instanceof HitField) {
- HitField hf = (HitField) value;
- if (getXmlEscape()) {
- return hf.quotedContent(getBoldOpenTag(),
- getBoldCloseTag(),
- getSeparatorTag(),
- true);
- } else {
- return hf.getContent(getBoldOpenTag(),
- getBoldCloseTag(),
- getSeparatorTag());
- }
- } else if (value instanceof StructuredData) {
- return value.toString();
- } else if (value instanceof XMLString || value instanceof JSONString) {
- return value.toString();
- } else if (getXmlEscape()) {
- return XML.xmlEscape(value.toString(), true, null);
- } else {
- return value.toString();
- }
- }
-
-}
diff --git a/container-search/src/main/java/com/yahoo/prelude/templates/LogExceptionUserTemplateDelegator.java b/container-search/src/main/java/com/yahoo/prelude/templates/LogExceptionUserTemplateDelegator.java
deleted file mode 100644
index 7696790897e..00000000000
--- a/container-search/src/main/java/com/yahoo/prelude/templates/LogExceptionUserTemplateDelegator.java
+++ /dev/null
@@ -1,201 +0,0 @@
-// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-package com.yahoo.prelude.templates;
-
-import com.yahoo.log.LogLevel;
-import com.yahoo.yolean.Exceptions;
-
-import java.io.IOException;
-import java.io.Writer;
-import java.util.Properties;
-import java.util.logging.Logger;
-
-/**
- * Delegates to another UserTemplate, but handles any exceptions(except IOException) by logging them.
- *
- * @author Tony Vaagenes
- * @deprecated use a renderer instead
- */
-@SuppressWarnings("deprecation")
-// TODO: Remove on Vespa 7
-@Deprecated // OK (But wait for deprecated handlers in vespaclient-container-plugin to be removed)
-public class LogExceptionUserTemplateDelegator<T extends Writer> extends UserTemplate<T> {
-
- private static Logger log = Logger.getLogger(LogExceptionUserTemplateDelegator.class.getName());
- private final UserTemplate<T> delegate;
-
- public LogExceptionUserTemplateDelegator(UserTemplate<T> delegate) {
- super(LogExceptionUserTemplateDelegator.class.getSimpleName());
- this.delegate = delegate;
- }
-
- @Override
- public Context createContext() {
- return delegate.createContext();
- }
-
- @Override
- public T wrapWriter(Writer writer) {
- return delegate.wrapWriter(writer);
- }
-
- @Override
- public boolean isDefaultTemplateSet() {
- return delegate.isDefaultTemplateSet();
- }
-
- @Override
- public String getSummaryClass() {
- return delegate.getSummaryClass();
- }
-
- @Override
- public String getBoldOpenTag() {
- return delegate.getBoldOpenTag();
- }
-
- @Override
- public String getBoldCloseTag() {
- return delegate.getBoldCloseTag();
- }
-
- @Override
- public String getSeparatorTag() {
- return delegate.getSeparatorTag();
- }
-
- @Override
- public void setSummaryClass(String summaryClass) {
- delegate.setSummaryClass(summaryClass);
- }
-
- @Override
- public void setHighlightTags(String start, String end, String sep) {
- delegate.setHighlightTags(start, end, sep);
- }
-
- @Override
- public String getName() {
- return delegate.getName();
- }
-
- @Override
- public String getMimeType() {
- return delegate.getMimeType();
- }
-
- @Override
- public String getEncoding() {
- return delegate.getEncoding();
- }
-
- @Override
- public Template<T> getTemplate(String templateName) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void setTemplate(String templateName, Template<? extends Writer> template) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void setTemplateNotNull(String templateName, Template<? extends Writer> template) {
- throw new UnsupportedOperationException();
- }
-
- /*** Template
-
- @Override
- public void <methodName>(Context context, T writer) throws IOException {
- try {
- delegate.<methodName>(context, writer);
- } catch (Exception e) {
- handleException(e);
- }
- }
-
- ***/
-
- /*** Begin expanded template for
- header, footer, hit, hitFooter, error, noHits, queryContext,
- Thanks java, for giving me the opportunely to use copy-paste ***/
-
-
- @Override
- public void header(Context context, T writer) throws IOException {
- try {
- delegate.header(context, writer);
- } catch (Exception e) {
- handleException(e);
- }
- }
-
- @Override
- public void footer(Context context, T writer) throws IOException {
- try {
- delegate.footer(context, writer);
- } catch (Exception e) {
- handleException(e);
- }
- }
-
- @Override
- public void hit(Context context, T writer) throws IOException {
- try {
- delegate.hit(context, writer);
- } catch (Exception e) {
- handleException(e);
- }
- }
-
- @Override
- public void hitFooter(Context context, T writer) throws IOException {
- try {
- delegate.hitFooter(context, writer);
- } catch (Exception e) {
- handleException(e);
- }
- }
-
- @Override
- public void error(Context context, T writer) throws IOException {
- try {
- delegate.error(context, writer);
- } catch (Exception e) {
- handleException(e);
- }
- }
-
- @Override
- public void noHits(Context context, T writer) throws IOException {
- try {
- delegate.noHits(context, writer);
- } catch (Exception e) {
- handleException(e);
- }
- }
-
- @Override
- public void queryContext(Context context, T writer) throws IOException {
- try {
- delegate.queryContext(context, writer);
- } catch (Exception e) {
- handleException(e);
- }
- }
-
- /*** End expanded template. ***/
-
- private void handleException(Exception e) throws IOException {
- if (e instanceof IOException) {
- throw (IOException) e;
- } else {
- log.log(LogLevel.WARNING, "Exception thrown in " + getName()
- + ": " + Exceptions.toMessageString(e), e);
- }
- }
-
- UserTemplate<T> getDelegate() {
- return delegate;
- }
-}
diff --git a/container-search/src/main/java/com/yahoo/prelude/templates/MapContext.java b/container-search/src/main/java/com/yahoo/prelude/templates/MapContext.java
deleted file mode 100644
index c08c9701741..00000000000
--- a/container-search/src/main/java/com/yahoo/prelude/templates/MapContext.java
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-package com.yahoo.prelude.templates;
-
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.LinkedHashMap;
-import java.util.Map;
-
-/**
- * A context having a map as secondary storage
- * @deprecated use a Renderer instead
- */
-@SuppressWarnings("deprecation")
-// TODO: Remove on Vespa 7
-@Deprecated // OK (But wait for deprecated handlers in vespaclient-container-plugin to be removed)
-public class MapContext extends Context {
-
- private Map<String, Object> map = new LinkedHashMap<>();
-
- @Override
- public Object get(String key) {
- return normalizeValue(map.get(key));
- }
-
- public Object put(String name, Object value) {
- return map.put(name, value);
- }
-
- public Object remove(Object name) {
- return map.remove(name);
- }
-
- @Override
- public Collection<? extends Object> getKeys() {
- return map.keySet();
- }
-
-}
diff --git a/container-search/src/main/java/com/yahoo/prelude/templates/PageTemplateSet.java b/container-search/src/main/java/com/yahoo/prelude/templates/PageTemplateSet.java
deleted file mode 100644
index cac06011679..00000000000
--- a/container-search/src/main/java/com/yahoo/prelude/templates/PageTemplateSet.java
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-package com.yahoo.prelude.templates;
-
-import com.yahoo.search.Result;
-import com.yahoo.search.result.Hit;
-import com.yahoo.search.result.HitGroup;
-import com.yahoo.text.XMLWriter;
-
-import java.io.IOException;
-import java.io.Writer;
-
-/**
- * A template implementing the 'page' format.
- * This is a variant of the tiled template set - see that class for details.
- *
- * @author bratseth
- * @deprecated use a Renderer instead
- */
-@SuppressWarnings("deprecation")
-// TODO: Remove on Vespa 7
-@Deprecated // OK
-public class PageTemplateSet extends TiledTemplateSet {
-
- public PageTemplateSet() {
- super("page");
- }
-
- @Override
- /** Uses an XML writer in this */
- public XMLWriter wrapWriter(Writer writer) { return new XMLWriter(super.wrapWriter(writer)); }
-
- @Override
- public void header(Context context,XMLWriter writer) throws IOException {
- Result result=(Result)context.get("result");
- writer.xmlHeader(getRequestedEncoding(result.getQuery()));
- writer.openTag("page").attribute("version","1.0").attribute("layout",result.hits().getField("layout"));
- renderCoverageAttributes(result.getCoverage(false), writer);
- writer.closeStartTag();
- renderSectionContent(result.hits(),writer);
- }
-
- @Override
- public void footer(Context context,XMLWriter writer) throws IOException {
- if (writer.isIn("content"))
- writer.closeTag();
- super.footer(context,writer);
- }
-
- @Override
- protected void renderSection(HitGroup hit, XMLWriter writer) throws IOException {
- writer.openTag("section");
- writer.attribute("id",hit.getDisplayId());
- writer.attribute("layout",hit.getField("layout"));
- writer.attribute("region",hit.getField("region"));
- writer.closeStartTag();
- renderSectionContent(hit,writer);
- }
-
- @Override
- public void hit(Context context, XMLWriter writer) throws IOException {
- Hit hit = (Hit) context.get("hit");
- if (!hit.isMeta() && !writer.isIn("content"))
- writer.openTag("content");
- super.hit(context,writer);
- }
-
- @Override
- public void hitFooter(Context context, XMLWriter writer) throws IOException {
- if (writer.isIn("content"))
- writer.closeTag();
- super.hitFooter(context, writer);
- }
-
- public String toString() { return "page template"; }
-
-}
diff --git a/container-search/src/main/java/com/yahoo/prelude/templates/SearchRendererAdaptor.java b/container-search/src/main/java/com/yahoo/prelude/templates/SearchRendererAdaptor.java
deleted file mode 100644
index 467cd615ebd..00000000000
--- a/container-search/src/main/java/com/yahoo/prelude/templates/SearchRendererAdaptor.java
+++ /dev/null
@@ -1,259 +0,0 @@
-// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-package com.yahoo.prelude.templates;
-
-import com.yahoo.prelude.fastsearch.GroupingListHit;
-import com.yahoo.search.Result;
-import com.yahoo.search.query.context.QueryContext;
-import com.yahoo.search.rendering.Renderer;
-import com.yahoo.search.result.*;
-import com.yahoo.search.result.ErrorHit;
-import com.yahoo.processing.request.ErrorMessage;
-import com.yahoo.search.result.Hit;
-import com.yahoo.text.XMLWriter;
-
-import java.io.*;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Iterator;
-
-/**
- * Renders a search result using the old templates API.
- *
- * @author Tony Vaagenes
- * @deprecated do not use
- */
-@SuppressWarnings({ "rawtypes", "deprecation", "unchecked" })
-@Deprecated // OK (But wait for deprecated handlers in vespaclient-container-plugin to be removed)
-// TODO: Remove on Vespa 7
-public final class SearchRendererAdaptor extends Renderer {
-
- private final LogExceptionUserTemplateDelegator templates;
-
- //Per instance members, must be created at rendering time, not construction time due to cloning.
- private Context context;
-
- public SearchRendererAdaptor(UserTemplate userTemplate) {
- templates = new LogExceptionUserTemplateDelegator(userTemplate);
- }
-
- @Override
- public void init() {
- super.init();
- context = templates.createContext();
- }
-
- /** A legacy test utility - do not use. */
- public static void callRender(OutputStream stream, Result result) throws IOException {
- Renderer rendererAdaptor = new SearchRendererAdaptor(result.getTemplating().getTemplates());
- rendererAdaptor.init();
- result.getTemplating().setRenderer(rendererAdaptor);
- rendererAdaptor.render(stream, result, result.getQuery().getModel().getExecution(), result.getQuery());
- }
-
- @Override
- public String getEncoding() {
- return templates.getEncoding();
- }
-
- @Override
- public String getMimeType() {
- return templates.getMimeType();
- }
-
- @Override
- public String getDefaultSummaryClass() {
- return templates.getSummaryClass();
- }
-
- /**
- * Renders this result
- */
- public void render(Writer writer, Result result) throws java.io.IOException {
- Writer wrappedWriter = wrapWriter(writer);
-
- beginResult(wrappedWriter, result);
-
- if (result.hits().getError() != null || result.hits().getQuery().errors().size() > 0) {
- error(wrappedWriter, Collections.unmodifiableCollection(
- all(result.hits().getQuery().errors(), result.hits().getError())));
- }
-
- if (result.getConcreteHitCount() == 0) {
- emptyResult(wrappedWriter, result);
- }
-
- if (result.getContext(false) != null) {
- queryContext(wrappedWriter, result.getContext(false));
- }
-
- renderHitGroup(wrappedWriter, result.hits(), result.hits().getQuery().getOffset() + 1);
-
- endResult(wrappedWriter, result);
- }
-
-
- private <T> Collection<T> all(Collection<T> collection, T extra) {
- Collection<T> result = new ArrayList<>(collection);
- result.add(extra);
- return result;
- }
-
-
- public Writer wrapWriter(Writer writer) {
- return templates.wrapWriter(writer);
- }
-
-
- public void beginResult(Writer writer, Result result) throws IOException {
- context.put("context", context);
- context.put("result", result);
- context.setBoldOpenTag(templates.getBoldOpenTag());
- context.setBoldCloseTag(templates.getBoldCloseTag());
- context.setSeparatorTag(templates.getSeparatorTag());
-
- templates.header(context, writer);
- }
-
- public void endResult(Writer writer, Result result) throws IOException {
- templates.footer(context, writer);
- }
-
- public void error(Writer writer, Collection<ErrorMessage> errorMessages) throws IOException {
- templates.error(context, writer);
- }
-
-
- public void emptyResult(Writer writer, Result result) throws IOException {
- templates.noHits(context, writer);
- }
-
- public void queryContext(Writer writer, QueryContext queryContext) throws IOException {
- templates.queryContext(context, writer);
- }
-
- private void renderHitGroup(Writer writer, HitGroup hitGroup, int hitnumber)
- throws IOException {
- boolean defaultTemplate = templates.isDefaultTemplateSet();
- for (Hit hit : hitGroup.asList()) {
- if (!defaultTemplate && hit instanceof ErrorHit) continue; // TODO: Stop doing this
-
- renderHit(writer, hit, hitnumber);
- if (!hit.isAuxiliary())
- hitnumber++;
- }
- }
-
-
- /**
- * Renders this hit as xml. The default implementation will call the simpleRender()
- * hook. If it returns true, nothing more is done, otherwise the
- * given template set will be used for rendering.
- *
- *
- * @param writer the writer to append this hit to
- * @throws java.io.IOException if rendering fails
- */
- public void renderHit(Writer writer, Hit hit, int hitno) throws IOException {
- renderRegularHit(writer, hit, hitno);
- }
-
- private void renderRegularHit(Writer writer, Hit hit, int hitno) throws IOException {
- boolean renderedSimple = simpleRenderHit(writer, hit);
-
- if (renderedSimple) {
- return;
- }
-
- HitContext hitContext = new HitContext(hit, context);
- hitContext.put("hit", hit);
- hitContext.put("hitno", Integer.valueOf(hitno));
- hitContext.put("relevancy",hit.getRelevance());
- templates.hit(hitContext, writer);
-
- if (hit instanceof HitGroup)
- renderHitGroup(writer, (HitGroup) hit, hitno);
-
- // Put these back - may have been changed by nested rendering
- hitContext.put("hit", hit);
- hitContext.put("hitno", Integer.valueOf(hitno));
- templates.hitFooter(hitContext, writer);
-
-
- hitContext.remove("hit");
- hitContext.remove("hitno");
- }
-
- private boolean simpleRenderHit(Writer writer, Hit hit) throws IOException {
- if (hit instanceof DefaultErrorHit) {
- return simpleRenderDefaultErrorHit(writer, (DefaultErrorHit) hit);
- } else if (hit instanceof GroupingListHit) {
- return true;
- } else {
- return false;
- }
- }
-
- public static boolean simpleRenderDefaultErrorHit(Writer writer, ErrorHit defaultErrorHit) throws IOException {
- XMLWriter xmlWriter=(writer instanceof XMLWriter) ? (XMLWriter)writer : new XMLWriter(writer,10,-1);
- xmlWriter.openTag("errordetails");
- for (Iterator i = defaultErrorHit.errorIterator(); i.hasNext();) {
- ErrorMessage error = (ErrorMessage) i.next();
- renderMessageDefaultErrorHit(xmlWriter, error);
- }
- xmlWriter.closeTag();
- return true;
- }
-
- public static void renderMessageDefaultErrorHit(XMLWriter writer, ErrorMessage error) throws IOException {
- writer.openTag("error");
- if (error instanceof com.yahoo.search.result.ErrorMessage)
- writer.attribute("source",((com.yahoo.search.result.ErrorMessage)error).getSource());
- writer.attribute("error",error.getMessage());
- writer.attribute("code",Integer.toString(error.getCode()));
- writer.content(error.getDetailedMessage(),false);
- if (error.getCause()!=null) {
- writer.openTag("cause");
- writer.content("\n",true);
- StringWriter stackTrace=new StringWriter();
- error.getCause().printStackTrace(new PrintWriter(stackTrace));
- writer.content(stackTrace.toString(),true);
- writer.closeTag();
- }
- writer.closeTag();
- }
-
- /**
- * Renders this hit as XML, disregarding the given template.
- * The main error will be rendered first, the all the following errors.
- */
- public boolean simpleRenderErrorHit(Writer writer, com.yahoo.search.result.ErrorHit errorHit) throws IOException {
- XMLWriter xmlWriter=(writer instanceof XMLWriter) ? (XMLWriter)writer : new XMLWriter(writer,10,-1);
- xmlWriter.openTag("errordetails");
- for (Iterator i = errorHit.errorIterator(); i.hasNext();) {
- ErrorMessage error = (ErrorMessage) i.next();
- rendererErrorHitMessageMessage(xmlWriter, errorHit, error);
- }
- xmlWriter.closeTag();
- return true;
- }
-
- public static void rendererErrorHitMessageMessage(XMLWriter writer, com.yahoo.search.result.ErrorHit errorHit, ErrorMessage error) throws IOException {
- writer.openTag("error");
- if (errorHit instanceof Hit) {
- writer.attribute("source", ((Hit) errorHit).getSource());
- }
- writer.attribute("error",error.getMessage());
- writer.attribute("code",Integer.toString(error.getCode()));
- writer.content(error.getDetailedMessage(),false);
- writer.closeTag();
- }
-
- /**
- * For internal use only
- */
- public UserTemplate getAdaptee() {
- return templates.getDelegate();
- }
-
-}
diff --git a/container-search/src/main/java/com/yahoo/prelude/templates/Template.java b/container-search/src/main/java/com/yahoo/prelude/templates/Template.java
deleted file mode 100644
index 761eb1db562..00000000000
--- a/container-search/src/main/java/com/yahoo/prelude/templates/Template.java
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-package com.yahoo.prelude.templates;
-
-import java.io.Writer;
-
-
-/**
- * A template turns a template string and some state into
- * an instantiated string. Add support for a particular
- * template mechanism by subclassing this.
- *
- * @author bratseth
- * @deprecated use a Renderer instead
- */
-@SuppressWarnings("deprecation")
-@Deprecated // OK (But wait for deprecated handlers in vespaclient-container-plugin to be removed)
-// TODO: Remove on Vespa 7
-public abstract class Template<T extends Writer> {
-
- /**
- * Renders this template
- *
- * @param context the context to evaluate in
- * @param writer the writer to render to
- */
- public abstract void render(Context context,T writer) throws java.io.IOException;
-
-
- /**
- * Get template name
- *
- * @return template name
- */
- public abstract String getName();
-
-}
diff --git a/container-search/src/main/java/com/yahoo/prelude/templates/TemplateSet.java b/container-search/src/main/java/com/yahoo/prelude/templates/TemplateSet.java
deleted file mode 100644
index 65a5b4cacfd..00000000000
--- a/container-search/src/main/java/com/yahoo/prelude/templates/TemplateSet.java
+++ /dev/null
@@ -1,218 +0,0 @@
-// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-package com.yahoo.prelude.templates;
-
-import com.yahoo.search.Result;
-import com.yahoo.search.result.Hit;
-import com.yahoo.text.GenericWriter;
-import com.yahoo.text.XMLWriter;
-
-import java.io.IOException;
-import java.io.Writer;
-
-/**
- * <p>A template set contains instances of the various templates
- * required to render a result.</p>
- *
- * <p>Normal usage is to create an instance and populate it with templates,
- * but this class also supports subclassing to refine the behaviour,
- * like returning different templates for different hit types.</p>
- *
- * @author bratseth
- * @deprecated use a renderer instead
- */
-@SuppressWarnings("deprecation")
-@Deprecated // OK (But wait for deprecated handlers in vespaclient-container-plugin to be removed)
-// TODO: Remove on Vespa 7
-public class TemplateSet<T extends Writer> extends UserTemplate<T> {
-
- private static final String queryContextTemplateName = "queryContext";
-
- private static final DefaultTemplateSet defaultTemplateSet=new DefaultTemplateSet();
-
- /**
- * Creates a template set containing no templates
- *
- * @param name the unique name of this template set, used for
- * refering to it by clients
- */
- public TemplateSet(String name,
- String mimeType,
- String encoding) {
- super(name, mimeType,encoding);
- }
-
- /**
- * Returns the default template set. This is a template set which renders in
- * the default xml format
- */
- public static UserTemplate<XMLWriter> getDefault() {
- return defaultTemplateSet;
- }
-
- /**
- * Returns the result header template
- *
- * @param result the result which will use the template
- * @return the template to use, never null
- */
- @SuppressWarnings("unchecked")
- public Template<T> getHeader(Result result) { return (Template<T>) getTemplate("header"); }
-
- /**
- * Sets the header template
- *
- * @param header the template to use for rendering getHeaders
- * @throws NullPointerException if the given template is null
- */
- public void setHeader(Template<T> header) {
- setTemplateNotNull("header",header);
- }
-
- /**
- * Returns the result footer template
- *
- * @param result the result which will use the template
- * @return the template to use, never null
- */
- @SuppressWarnings("unchecked")
- public Template<T> getFooter(Result result) { return (Template<T>) getTemplate("footer"); }
-
- /**
- * Sets the footer template
- *
- * @param footer the template to use for rendering footers
- * @throws NullPointerException if the given template is null
- */
- public void setFooter(Template<T> footer) {
- setTemplateNotNull("footer",footer);
- }
-
- /**
- * Returns the empty body template
- *
- * @param result the result which will use the template
- * @return the template to use, never null
- */
- @SuppressWarnings("unchecked")
- public Template<T> getNohits(Result result) { return (Template<T>) getTemplate("nohits"); }
-
-
- /**
- * @return the template for rendering the query context, never null
- */
- @SuppressWarnings("unchecked")
- public Template<T> getQueryContext(Result result) {
- return (Template<T>) getTemplate(queryContextTemplateName);
- }
-
- /**
- * @param template The template to be used for rendering query contexts, never null.
- */
- public void setQueryContext(Template<T> template) {
- setTemplateNotNull(queryContextTemplateName, template);
- }
-
- /**
- * Sets the nohits template
- *
- * @param nohits the template to use for rendering empty results
- * @throws NullPointerException if the given template is null
- */
- public void setNohits(Template<T> nohits) {
- setTemplateNotNull("nohits",nohits);
- }
-
- /**
- * Returns the error body template
- *
- * @param result the result which will use the template
- * @return the template to use, never null
- */
- @SuppressWarnings("unchecked")
- public Template<T> getError(Result result) { return (Template<T>) getTemplate("error"); }
-
- /**
- * Sets the error template
- *
- * @param error the template to use for rendering errors
- * @throws NullPointerException if the given template is null
- */
- public void setError(Template<T> error) {
- setTemplateNotNull("error",error);
- }
-
- /**
- * Returns the hit template
- *
- * @param resultHit the hit which will use the template
- * @return the template to use, never null
- */
- @SuppressWarnings("unchecked")
- public Template<T> getHit(Hit resultHit) { return (Template<T>) getTemplate("hit"); }
-
- /**
- * Sets the hit template
- *
- * @param hit the template to use for rendering hits
- * @throws NullPointerException if the given template is null
- */
- public void setHit(Template<T> hit) {
- setTemplateNotNull("hit",hit);
- }
-
- /**
- * Returns the hit footer template
- *
- * @param hit the hit which will use the template
- * @return the template to use, or null if no hit footer is used
- */
- @SuppressWarnings("unchecked")
- public Template<T> getHitFooter(Hit hit) { return (Template<T>) getTemplate("hitfooter"); }
-
- public String toString() {
- return "template set " + getName() + " of type " + getMimeType() +
- " [header=" + getTemplate("header") +
- ",footer=" + getTemplate("footer") +
- ",nohits=" + getTemplate("nohits") +
- ",error=" + getTemplate("error") +
- ",hit=" + getTemplate("hit") + "]";
- }
-
- @Override
- public void header(Context context, T writer) throws IOException {
- getHeader(null).render(context, writer);
- }
-
- @Override
- public void footer(Context context, T writer) throws IOException {
- getFooter(null).render(context, writer);
- }
-
- @Override
- public void hit(Context context, T writer) throws IOException {
- getHit(null).render(context, writer);
- }
-
- @Override
- public void error(Context context, T writer) throws IOException {
- getError(null).render(context, writer);
- }
-
- @Override
- public void hitFooter(Context context, T writer) throws IOException {
- Template<T> hitFooter = getHitFooter(null);
- if (hitFooter != null)
- hitFooter.render(context, writer);
- }
-
- @Override
- public void noHits(Context context, T writer) throws IOException {
- getNohits(null).render(context, writer);
- }
-
- @Override
- public void queryContext(Context context, T writer) throws IOException {
- getQueryContext(null).render(context, writer);
- }
-
-}
diff --git a/container-search/src/main/java/com/yahoo/prelude/templates/TiledTemplateSet.java b/container-search/src/main/java/com/yahoo/prelude/templates/TiledTemplateSet.java
deleted file mode 100644
index 2fa6e14019e..00000000000
--- a/container-search/src/main/java/com/yahoo/prelude/templates/TiledTemplateSet.java
+++ /dev/null
@@ -1,356 +0,0 @@
-// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-package com.yahoo.prelude.templates;
-
-import com.yahoo.prelude.hitfield.HitField;
-import com.yahoo.prelude.hitfield.JSONString;
-import com.yahoo.prelude.hitfield.XMLString;
-import com.yahoo.prelude.templates.FormattingOptions.SubtypeFieldWithPrefix;
-import com.yahoo.search.Result;
-import com.yahoo.search.pagetemplates.model.Renderer;
-import com.yahoo.search.pagetemplates.model.Source;
-import com.yahoo.search.pagetemplates.result.SectionHitGroup;
-import com.yahoo.search.result.Hit;
-import com.yahoo.search.result.HitGroup;
-import com.yahoo.search.result.StructuredData;
-import com.yahoo.text.XML;
-import com.yahoo.text.XMLWriter;
-
-import java.io.IOException;
-import java.io.Writer;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.stream.Collectors;
-
-/**
- * A template set which implements the 'tiled' format.
- *
- * This template implementation requires a few rules to be observed for it to work properly:
- * <ul>
- * <li>As hit fields are rendered as XML tag names, their name must be compatible with XML tag names.</li>
- * <li>Results sections, meta section, provider tags are rendered based on hits having specific types (as in {@link Hit#types()},
- * see table below for a list of hit types that are needed in order for hits to render properly.</li>
- * <li>Some fields inside hits corresponding to provider tags (/result/meta/provider) are formatted in a specific way, see provider fields formatting options
- * below. Other fields are rendered the usual way.</li>
- * </ul>
- *
- * <p>Hit types required for proper rendering</p>
- * <table summary="Hit types required for proper rendering">
- * <tr><td>XML tag path</td><td>Required hit type</td></tr>
- * <tr><td>/result/section</td><td>A hit group and have a "section" type</td></tr>
- * <tr><td>/result/meta</td><td>A hit group and have a "meta" type</td></tr>
- * <tr><td>/result/meta/provider</td><td>A hit that has a "logging" type</td></tr>
- * </table>
- *
- * <p>Provider fields formatting options</p>
- * <table summary="Provider fields formatting options">
- * <tr><td>Field</td><td>Formatting</td><td>Field type</td></tr>
- * <tr><td>provider</td><td>name attribute of &lt;provider&gt; tag</td><td>Provided by container</td></tr>
- * <tr><td>scheme</td><td>scheme attribute of &lt;provider&gt; tag</td><td>Provided by container</td></tr>
- * <tr><td>host</td><td>host attribute of &lt;provider&gt; tag</td><td>Provided by container</td></tr>
- * <tr><td>port</td><td>port attribute of &lt;provider&gt; tag</td><td>Provided by container</td></tr>
- * <tr><td>path</td><td>path attribute of &lt;provider&gt; tag</td><td>Provided by container</td></tr>
- * <tr><td>status</td><td>result attribute of &lt;provider&gt; tag</td><td>Provided by container</td></tr>
- * <tr><td>latency_connect</td><td>&lt;latency type="connect"&gt; tag</td><td>Provided by container</td></tr>
- * <tr><td>latency_start</td><td>&lt;latency type="start"&gt; tag</td><td>Provided by container</td></tr>
- * <tr><td>latency_finish</td><td>&lt;latency type="finish"&gt; tag</td><td>Provided by container</td></tr>
- * <tr><td>query_param_*</td><td>&lt;parameter name="..."&gt; tag</td><td>Provided by container</td></tr>
- * <tr><td>header_*</td><td>&lt;header name="..."&gt; tag</td><td>Provided by container</td></tr>
- * <tr><td>response_header_*</td><td>&lt;response-header name="..."&gt; tag</td><td>Provided by container</td></tr>
- * <tr><td>count_first</td><td>&lt;count type="first"&gt; tag</td><td>Provided by container</td></tr>
- * <tr><td>count_last</td><td>&lt;count type="last"&gt; tag</td><td>Provided by container</td></tr>
- * <tr><td>count_total</td><td>&lt;count type="total"&gt; tag</td><td>Provided by container</td></tr>
- * <tr><td>count_deep</td><td>&lt;count type="deep"&gt; tag</td><td>Provided by container</td></tr>
- * <tr><td>queryattrs_xorronum</td><td>&lt;queryattrs name="xorronum"&gt; tag</td><td>Provided by YST searcher</td></tr>
- * <tr><td>queryattrs_RankFeaturesRewriterAttr</td><td>&lt;queryattrs name="RankFeaturesRewriterAttr"&gt; tag</td><td>Provided by YST searcher</td></tr>
- * <tr><td>queryattrs_intlannotator</td><td>&lt;queryattrs name="intlannotator"&gt; tag</td><td>Provided by YST searcher</td></tr>
- * <tr><td>queryattrs_category</td><td>&lt;queryattrs name="category"&gt; tag</td><td>Provided by YST searcher</td></tr>
- * <tr><td>wordcounts_*</td><td>&lt;wordcounts word="..."&gt; tag</td><td>Provided by YST searcher</td></tr>
- * </table>
- *
- * @author bratseth
- * @author laboisse
- * @deprecated use a Renderer instead
- */
-@SuppressWarnings("deprecation")
-// TODO: Remove on Vespa 7
-@Deprecated // OK
-public class TiledTemplateSet extends DefaultTemplateSet {
-
- private FormattingOptions hitOptionsForProvider;
- private FormattingOptions hitOptions;
-
- public TiledTemplateSet() {
- this("tiled");
- }
-
- public TiledTemplateSet(String templateName) {
- super(templateName);
-
- // Define formatting options that will be used by various rendering methods
- hitOptions = new FormattingOptions();
- // Render provider field as an attribute, not as a regular field
- hitOptions.formatFieldAsAttribute("provider", "provider");
- hitOptions.setFieldNotToRender("provider");
-
-
- // Define formatting options that will be used by various rendering methods, for /result/meta/provider tags
- hitOptionsForProvider = new FormattingOptions();
- hitOptionsForProvider.formatFieldAsAttribute("provider", "name"); // Provider name is rendered a provider/@name
- // hitOptionsForProvider.formatFieldAsAttribute("uri", "query"); // FIXME Issue with attribute formatting, keeping as regular field for now
- hitOptionsForProvider.formatFieldAsAttribute("scheme", "scheme");
- hitOptionsForProvider.formatFieldAsAttribute("host", "host");
- hitOptionsForProvider.formatFieldAsAttribute("port", "port");
- hitOptionsForProvider.formatFieldAsAttribute("path", "path");
- hitOptionsForProvider.formatFieldAsAttribute("status", "result");
- // Latency fields are not defined using prefixes as we know all the field names and prefixes are expensive
- hitOptionsForProvider.formatFieldWithSubtype("latency_connect", "latency", "type", "connect");
- hitOptionsForProvider.formatFieldWithSubtype("latency_start", "latency", "type", "start");
- hitOptionsForProvider.formatFieldWithSubtype("latency_finish", "latency", "type", "finish");
- // Must use prefix for query parameters
- hitOptionsForProvider.formatFieldWithSubtype("query_param_", "parameter", "name");
- // Must use prefix for getHeaders
- hitOptionsForProvider.formatFieldWithSubtype("header_", "header", "name");
- // Must use prefix for response getHeaders
- hitOptionsForProvider.formatFieldWithSubtype("response_header_", "response-header", "name");
- // Count fields are not defined using prefixes as we know all the field names and prefixes are expensive
- hitOptionsForProvider.formatFieldWithSubtype("count_first", "count", "type", "first");
- hitOptionsForProvider.formatFieldWithSubtype("count_last", "count", "type", "last");
- hitOptionsForProvider.formatFieldWithSubtype("count_total", "count", "type", "total");
- hitOptionsForProvider.formatFieldWithSubtype("count_deep", "count", "type", "deep");
-
- hitOptionsForProvider.formatFieldWithSubtype("queryattrs_xorronum", "queryattrs", "name", "xorronum");
- hitOptionsForProvider.formatFieldWithSubtype("queryattrs_RankFeaturesRewriterAttr", "queryattrs", "name", "RankFeaturesRewriterAttr");
- hitOptionsForProvider.formatFieldWithSubtype("queryattrs_intlannotator", "queryattrs", "name", "intlannotator");
- hitOptionsForProvider.formatFieldWithSubtype("queryattrs_category", "queryattrs", "name", "category");
-
- hitOptionsForProvider.formatFieldWithSubtype("wordcounts_", "wordcounts", "word");
- // Provider field should not be rendered in logging hits as we already have <provider name="...">
- hitOptionsForProvider.setFieldNotToRender("provider");
- }
-
- @Override
- /** Uses an XML writer in this template */
- public XMLWriter wrapWriter(Writer writer) { return new XMLWriter(super.wrapWriter(writer)); }
-
- @Override
- public void header(Context context,XMLWriter writer) throws IOException {
- Result result=(Result)context.get("result");
- writer.xmlHeader(getRequestedEncoding(result.getQuery()));
- writer.openTag("result").attribute("version","1.0");
- writer.attribute("layout", result.hits().getField("layout"));
- renderCoverageAttributes(result.getCoverage(false), writer);
- writer.closeStartTag();
- renderSectionContent(result.hits(),writer);
- }
-
- /**
- * Augments default hit attributes rendering with formatting options.
- * There's also a hacky part: if hit is actually a hit group, tries to use
- * the 'type' field in place of the hit's type, to avoid having the 'group' hit type.
- */
- @Override
- protected void renderHitAttributes(Hit hit, XMLWriter writer) throws IOException {
- if (hit instanceof HitGroup) {
- String type = hit.types().stream().collect(Collectors.joining(" "));
- if ("group".equals(type))
- type = String.valueOf(hit.getField("type"));
- writer.attribute("type", type);
- }
- else {
- writer.attribute("type", hit.types().stream().collect(Collectors.joining(" ")));
- }
-
- if (hit.getRelevance() != null)
- writer.attribute("relevance", hit.getRelevance());
- writer.attribute("source", hit.getSource());
-
- for (Map.Entry<String, String> attr : hitOptions.fieldsAsAttributes()) {
- Object val = hit.getField(attr.getKey());
- if (val != null)
- writer.attribute(attr.getValue(), String.valueOf(val));
- }
- }
-
- @Override
- protected void renderField(Context context, Hit hit, Map.Entry<String, Object> entry, XMLWriter writer) throws IOException {
- String fieldName = entry.getKey();
-
- if ( !shouldRenderField(hit, fieldName)) return;
-
- writer.openTag(fieldName);
- renderFieldContent(context, hit, fieldName, writer);
- writer.closeTag();
- }
-
- /** Renders all fields of the hit */
- @Override
- protected void renderHitFields(Context context, Hit hit, XMLWriter writer) throws IOException {
- renderId(hit.getId(), writer);
- for (Iterator<Map.Entry<String, Object>> it = hit.fieldIterator(); it.hasNext(); ) {
- Map.Entry<String, Object> entry = it.next();
- // Exclude fields that should not be rendered
- if (hitOptions.shouldRenderField(entry.getKey()))
- renderField(context, hit, entry, writer);
- }
- }
-
- @Override
- protected boolean shouldRenderField(Hit hit, String fieldName) {
- if (fieldName.equals("relevancy")) return false;
- if (fieldName.equals("collapseId")) return false;
- return true;
- }
-
- /**
- * Overrides {@link DefaultTemplateSet#hit(Context, Writer)}
- * to print 'logging' type meta hits as /result/meta/provider tags.
- * Fails back to {@code super.hit(context, writer)} in other cases.
- */
- @Override
- public void hit(Context context, XMLWriter writer) throws IOException {
- Hit hit = (Hit) context.get("hit");
- if (hit.isMeta() && hit.types().contains("logging"))
- renderProvider(context, hit, writer);
- else
- super.hit(context, writer);
- }
-
- /**
- * Overrides {@link DefaultTemplateSet#renderHitGroup(HitGroup, Context, XMLWriter)}
- * for /result/section and /result/meta hit groups.
- * Fails back to {@code super.renderHitGroup(hit, context, writer)} otherwise.
- */
- @Override
- protected void renderHitGroup(HitGroup hit, Context context, XMLWriter writer) throws IOException {
- if (hit.types().contains("section")) {
- renderSection(hit, writer); // Renders /result/section
- }
- else if (hit.types().contains("meta")) {
- writer.openTag("meta"); // renders /result/meta
- writer.closeStartTag();
- }
- else {
- super.renderHitGroup(hit, context, writer);
- }
- }
-
- /**
- * Renders /result/section.
- * Doesn't use {@link #renderHitAttributes(Hit, XMLWriter)}.
- */
- protected void renderSection(HitGroup hit, XMLWriter writer) throws IOException {
- writer.openTag("section");
- writer.attribute("id",hit.getDisplayId());
- writer.attribute("layout",hit.getField("layout"));
- writer.attribute("region",hit.getField("region"));
- writer.attribute("placement",hit.getField("placement")); // deprecated in 5.0
- writer.closeStartTag();
- renderSectionContent(hit,writer);
- }
-
- protected void renderSectionContent(HitGroup hit,XMLWriter writer) throws IOException {
- if (hit instanceof SectionHitGroup) { // render additional information
- SectionHitGroup sectionGroup=(SectionHitGroup)hit;
- for (Source source : sectionGroup.sources()) {
- writer.openTag("source").attribute("url",source.getUrl());
- renderParameters(source.parameters(),writer);
- writer.closeTag();
- }
- for (Renderer renderer : sectionGroup.renderers()) {
- writer.openTag("renderer").attribute("for",renderer.getRendererFor()).attribute("name",renderer.getName());
- renderParameters(renderer.parameters(),writer);
- writer.closeTag();
- }
- }
- }
-
- private void renderParameters(Map<String,String> parameters,XMLWriter writer) throws IOException {
- // Render content
- for (Map.Entry<String, String> parameter : parameters.entrySet())
- writer.openTag("parameter").attribute("name",parameter.getKey()).content(parameter.getValue(),false).closeTag();
- }
-
- /**
- * Renders /result/meta/provider.
- * Uses {@link #renderProviderHitAttributes(Hit, XMLWriter)} instead of the default {@link #renderHitAttributes(Hit, XMLWriter)}.
- * @see #renderProviderHitAttributes(Hit, XMLWriter)
- * @see #renderProviderHitFields(Context, Hit, XMLWriter)
- */
- protected void renderProvider(Context context, Hit hit, XMLWriter writer)
- throws IOException {
- writer.openTag("provider");
- renderProviderHitAttributes(hit, writer);
- writer.closeStartTag();
- renderProviderHitFields(context, hit, writer);
- }
-
- /**
- * Specific hit attributes rendering for 'provider' meta hits under /result/meta.
- */
- protected void renderProviderHitAttributes(Hit hit, XMLWriter writer) throws IOException {
- // Browse through fields that should be rendered as attributes
- for (Map.Entry<String, String> attr : hitOptionsForProvider.fieldsAsAttributes())
- writer.attribute(attr.getValue(),hit.getField(attr.getKey()));
- }
-
-
- /**
- * Renders fields under /result/meta/provider.
- *
- * @see #renderProviderField(Context, Hit, java.util.Map.Entry, XMLWriter)
- */
- protected void renderProviderHitFields(Context context, Hit hit, XMLWriter writer)
- throws IOException {
- renderId(hit.getId(), writer);
- for (Iterator<Map.Entry<String, Object>> it = hit.fieldIterator(); it.hasNext(); ) {
- Map.Entry<String, Object> entry = it.next();
- // Exclude fields that have already been rendered as attributes and
- // fields that should not be rendered
- if (hitOptionsForProvider.getAttributeName(entry.getKey()) == null
- && hitOptionsForProvider.shouldRenderField(entry.getKey()))
- renderProviderField(context, hit, entry, writer);
- }
- }
-
- /**
- * Renders one field under /result/meta/provider.
- */
- protected void renderProviderField(Context context, Hit hit,
- Map.Entry<String, Object> entry, XMLWriter writer) throws IOException {
-
- String name = entry.getKey();
- FormattingOptions.SubtypeField subtypeField = hitOptionsForProvider.getSubtype(name);
- if (subtypeField == null)
- subtypeField = hitOptionsForProvider.getSubtypeWithPrefix(name);
-
- if (subtypeField != null) {
- writer.openTag(subtypeField.tagName);
- if (subtypeField.attributeValue != null) {
- writer.attribute(subtypeField.attributeName,subtypeField.attributeValue);
- }
- else if (subtypeField instanceof SubtypeFieldWithPrefix) {
- // This is a subtype field that was defined using a prefix
- // get the remaining part of the field name
- writer.attribute(subtypeField.attributeName,
- name.substring(((SubtypeFieldWithPrefix)subtypeField).prefixLength));
- }
- } else {
- writer.openTag(name);
- }
- writer.escapedContent(asXML(hit.getField(name)),false).closeTag();
- }
-
- private String asXML(Object value) {
- if (value == null)
- return "(null)";
- else if (value instanceof HitField)
- return ((HitField)value).quotedContent(false);
- else if (value instanceof StructuredData || value instanceof XMLString || value instanceof JSONString)
- return value.toString();
- else
- return XML.xmlEscape(value.toString(), false, '\u001f');
- }
-
- public String toString() { return "tiled result template"; }
-
-}
diff --git a/container-search/src/main/java/com/yahoo/prelude/templates/UserTemplate.java b/container-search/src/main/java/com/yahoo/prelude/templates/UserTemplate.java
deleted file mode 100644
index bcdf3311c1f..00000000000
--- a/container-search/src/main/java/com/yahoo/prelude/templates/UserTemplate.java
+++ /dev/null
@@ -1,312 +0,0 @@
-// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-package com.yahoo.prelude.templates;
-
-import com.yahoo.io.ByteWriter;
-import com.yahoo.prelude.fastsearch.FastHit;
-import com.yahoo.prelude.fastsearch.XMLField;
-import com.yahoo.search.Result;
-import com.yahoo.text.Utf8String;
-import com.yahoo.text.XMLWriter;
-
-import java.io.IOException;
-import java.io.Writer;
-import java.util.logging.Logger;
-
-
-/**
- * A wrapper for a template set, suitable for subclassing.
- *
- * <p>
- * A subclass of UserTemplate must implement header(), footer(), hit(),
- * hitFooter(), error() and noHits().
- *
- * @deprecated use a renderer instead
- * @author Steinar Knutsen
- */
-@SuppressWarnings("deprecation")
-@Deprecated // OK (But wait for deprecated handlers in vespaclient-container-plugin to be removed)
-// TODO: Remove on Vespa 7
-public abstract class UserTemplate<T extends Writer> extends GenericTemplateSet {
-
- // &amp;
- private static final byte[] ampersand = new byte[] { 38, 97, 109, 112, 59 };
-
- // &lt;
- private static final byte[] lessThan = new byte[] { 38, 108, 116, 59 };
- // &gt;
- private static final byte[] greaterThan = new byte[] { 38, 103, 116, 59 };
-
- // \\u00
- private static final byte[] quotePrefix = new byte[] { 92, 117, 48, 48 };
-
- private static final Logger log = Logger.getLogger(UserTemplate.class.getName());
-
- /**
- * The signature of this constructor is the one which is invoked
- * in a production setting.
- */
- public UserTemplate(String name, String mimeType,
- String encoding) {
- super(name, mimeType, encoding);
- }
-
- public UserTemplate(String name) {
- this(name,
- DEFAULT_MIMETYPE,
- DEFAULT_ENCODING
- );
- }
-
- /**
- * This is called once before each result is rendered using this template.
- * The returned writer is used in all subsequent calls. Use this if another (wrapper)
- * writer of the raw incoming writer is desired in the implementation of this template.
- * The class of the returned type must be given as a type argument to the template class,
- * to be able to implement methods taking this wrapper writer as the argument type.
- * This default implementation returns an XMLWriter.
- */
- @SuppressWarnings("unchecked")
- public T wrapWriter(Writer writer) {
- //FIXME: Hack
- return (T) XMLWriter.from(writer, 10, -1);
- }
-
- /**
- * Creates a new context suitable for this template.
- * The context may be reused for several evaluations, but not multiple
- * concurrent evaluations
- */
- public Context createContext() {
- return new MapContext();
- }
-
-
- /**
- * For internal use only
- * TODO: get rid of this method *
- */
- public boolean isDefaultTemplateSet() {
- return getClass().equals(TemplateSet.getDefault().getClass());
- }
-
- /**
- * Render the result set header.
- *
- * <p>
- * The result set is available in the context object under the name
- * "result".
- *
- * @param context
- * wrapper which will contain, among other thing, the result
- * set instance
- * @param writer
- * the destination for rendering the result
- * @throws IOException
- * may be propagated from the writer
- */
- public abstract void header(Context context, T writer)
- throws IOException;
-
- /**
- * Render the result set footer.
- *
- * <p>
- * The result set is available in the context object under the name
- * "result".
- *
- * @param context
- * wrapper which will contain, among other thing, the result
- * set instance
- * @param writer
- * the destination for rendering the result
- * @throws IOException
- * may be propagated from the writer
- */
- public abstract void footer(Context context, T writer)
- throws IOException;
-
- /**
- * Render a single top level hit.
- *
- * <p>
- * The result set is available in the context object under the name
- * "result". The hit itself as "hit", the index of the hit as "hitno", and
- * all the fields under their normal names.
- *
- * @param context
- * wrapper which will contain, among other thing, the hit
- * instance
- * @param writer
- * the destination for rendering the hit
- * @throws IOException
- * may be propagated from the writer
- */
- public abstract void hit(Context context, T writer) throws IOException;
-
- /**
- * Render a footer for a single top level hit. A typical implementation may
- * do nothing.
- *
- * <p>
- * The result set is available in the context object under the name
- * "result". The hit itself as "hit", the index of the hit as "hitno", and
- * all the fields under their normal names.
- *
- * @param context
- * wrapper which will contain, among other thing, the hit
- * instance
- * @param writer
- * the destination for rendering the hit
- * @throws IOException
- * may be propagated from the writer
- */
- public abstract void hitFooter(Context context, T writer)
- throws IOException;
-
- /**
- * Render the error message for a result set.
- *
- * <p>
- * The result set is available in the context object under the name
- * "result".
- *
- * @param context
- * wrapper which will contain, among other thing, main error
- * and result set instances.
- * @param writer
- * the destination for rendering the hit
- * @throws IOException
- * may be propagated from the writer
- */
- public abstract void error(Context context, T writer)
- throws IOException;
-
- /**
- * Invoked when the result set has no hits.
- *
- * <p>
- * The result set is available in the context object under the name
- * "result".
- *
- * @param context
- * wrapper which will contain, among other thing, the result
- * set instance
- * @param writer
- * the destination for rendering the hit
- * @throws IOException
- * may be propagated from the writer
- */
- public abstract void noHits(Context context, T writer)
- throws IOException;
-
- /**
- * Override this to add custom rendering for the query context of the result.
- * Only called when the query context is present.
- *
- * <p>
- * The result set is available in the context object under the name
- * "result". The query context is retrieved from the result by calling
- * result.getQuery.getContext(false)
- *
- * @param context
- * wrapper which will contain, among other things, the result
- * set instance
- * @param writer
- * the destination for rendering the hit
- * @throws IOException
- * may be propagated from the writer
- */
- public void queryContext(Context context, T writer) throws IOException {
- Result result = (Result) context.get("result");
- result.getContext(false).render(writer);
- }
-
- /**
- * Dump UTF-8 byte array to writer, but escape low ASCII codes except
- * TAB, NL and CR, and escape ampersand, less than and greater than.
- *
- * <p>
- * It is presumed the writer is buffered (which is the case in normal
- * result rendering), as the method may perform a large number of write
- * operations.
- *
- * <p>
- * public only for testing.
- */
- public static void dumpAndXMLQuoteUTF8(ByteWriter writer, byte[] utf) throws java.io.IOException {
- int startDump = 0;
-
- for (int i = 0; i < utf.length; ++i) {
- byte b = utf[i];
- if (b < 0) {
- // Not ASCII, above character 127
- // Don't try to do something smart with UNICODE characters,
- // just pass them through.
- } else if (b < 32) {
- switch (b) {
- case 9:
- case 10:
- case 13:
- break;
- default:
- writer.append(utf, startDump, i - startDump);
- startDump = i + 1;
- quoteByte(writer, b);
- break;
- }
- } else {
- // printable ASCII
- // quote special characters, otherwise do nothing
- switch (b) {
- // case 34: // double quote
- // writer.append(utf, startDump, i - startDump);
- // startDump = i + 1;
- // writer.append(doubleQuote);
- // break;
- case 38: // ampersand
- writer.append(utf, startDump, i - startDump);
- startDump = i + 1;
- writer.append(ampersand);
- break;
- case 60: // less than
- writer.append(utf, startDump, i - startDump);
- startDump = i + 1;
- writer.append(lessThan);
- break;
- case 62: // greater than
- writer.append(utf, startDump, i - startDump);
- startDump = i + 1;
- writer.append(greaterThan);
- break;
- }
- }
- }
- if (startDump < utf.length) {
- writer.append(utf, startDump, utf.length - startDump);
- }
- }
-
- /**
- * If the field is available as a UTF-8 byte array,
- * dump it to the writer.
- */
- public static boolean dumpBytes(ByteWriter writer,
- FastHit hit,
- String fieldName) throws java.io.IOException {
- return false;
- }
-
- private static void quoteByte(ByteWriter writer, byte b) throws java.io.IOException {
- byte[] quoted = new byte[2];
- writer.append(quotePrefix);
- quoted[0] = (byte) ((b >>> 4) + 0x30);
- if (quoted[0] > 0x39) {
- quoted[0] = (byte) (quoted[0] + 7);
- }
- quoted[1] = (byte) ((b & 0x0f) + 0x30);
- if (quoted[1] > 0x39) {
- quoted[1] = (byte) (quoted[1] + 7);
- }
- writer.append(quoted);
- }
-}
diff --git a/container-search/src/main/java/com/yahoo/prelude/templates/package-info.java b/container-search/src/main/java/com/yahoo/prelude/templates/package-info.java
deleted file mode 100644
index 2363a12c78d..00000000000
--- a/container-search/src/main/java/com/yahoo/prelude/templates/package-info.java
+++ /dev/null
@@ -1,7 +0,0 @@
-// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-@ExportPackage
-@PublicApi
-package com.yahoo.prelude.templates;
-
-import com.yahoo.api.annotations.PublicApi;
-import com.yahoo.osgi.annotation.ExportPackage;