aboutsummaryrefslogtreecommitdiffstats
path: root/container-search/src/main/java/com/yahoo/prelude/templates/DefaultTemplateSet.java
diff options
context:
space:
mode:
Diffstat (limited to 'container-search/src/main/java/com/yahoo/prelude/templates/DefaultTemplateSet.java')
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/templates/DefaultTemplateSet.java299
1 files changed, 0 insertions, 299 deletions
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;
- }
-
-
-
-}