From 9f7075ee040fd5c293880955ff55ac186c7a2efe Mon Sep 17 00:00:00 2001 From: Jon Bratseth Date: Fri, 9 Nov 2018 10:05:37 +0100 Subject: Remove template support --- .../java/com/yahoo/prelude/templates/Context.java | 116 ------- .../prelude/templates/DefaultTemplateSet.java | 299 ----------------- .../yahoo/prelude/templates/FormattingOptions.java | 193 ----------- .../prelude/templates/GenericTemplateSet.java | 158 --------- .../com/yahoo/prelude/templates/HitContext.java | 147 --------- .../LogExceptionUserTemplateDelegator.java | 201 ------------ .../com/yahoo/prelude/templates/MapContext.java | 38 --- .../yahoo/prelude/templates/PageTemplateSet.java | 76 ----- .../prelude/templates/SearchRendererAdaptor.java | 259 --------------- .../java/com/yahoo/prelude/templates/Template.java | 36 --- .../com/yahoo/prelude/templates/TemplateSet.java | 218 ------------- .../yahoo/prelude/templates/TiledTemplateSet.java | 356 --------------------- .../com/yahoo/prelude/templates/UserTemplate.java | 312 ------------------ .../com/yahoo/prelude/templates/package-info.java | 7 - .../src/main/java/com/yahoo/search/Result.java | 26 +- .../com/yahoo/search/handler/SearchHandler.java | 17 +- .../yahoo/search/rendering/RendererRegistry.java | 22 -- .../java/com/yahoo/search/result/Templating.java | 215 ------------- .../yahoo/prelude/templates/test/BoomTemplate.java | 51 --- .../templates/test/GroupedResultTestCase.java | 71 ---- .../prelude/templates/test/HitContextTestCase.java | 26 -- .../prelude/templates/test/TemplateTestCase.java | 55 ---- .../yahoo/prelude/templates/test/TestTemplate.java | 53 --- .../templates/test/templates/asearch/error.templ | 1 - .../templates/test/templates/asearch/footer.templ | 1 - .../templates/test/templates/asearch/header.templ | 1 - .../templates/test/templates/asearch/hit.templ | 1 - .../templates/test/templates/asearch/nohits.templ | 1 - .../test/templates/cgi-bin/asearch/error.templ | 1 - .../test/templates/cgi-bin/asearch/footer.templ | 1 - .../test/templates/cgi-bin/asearch/header.templ | 1 - .../test/templates/cgi-bin/asearch/hit.templ | 1 - .../test/templates/cgi-bin/asearch/nohits.templ | 1 - .../templates/test/templates/xsearch/error.templ | 1 - .../templates/test/templates/xsearch/footer.templ | 1 - .../templates/test/templates/xsearch/header.templ | 2 - .../templates/test/templates/xsearch/hit.templ | 5 - .../templates/test/templates/xsearch/nohits.templ | 1 - .../yahoo/prelude/templates/test/tilingexample.xml | 65 ---- .../prelude/templates/test/tilingexample2.xml | 23 -- .../handler/test/JSONSearchHandlerTestCase.java | 36 --- .../search/handler/test/SearchHandlerTestCase.java | 67 +--- .../yahoo/search/result/TemplatingTestCase.java | 174 ---------- 43 files changed, 18 insertions(+), 3319 deletions(-) delete mode 100644 container-search/src/main/java/com/yahoo/prelude/templates/Context.java delete mode 100644 container-search/src/main/java/com/yahoo/prelude/templates/DefaultTemplateSet.java delete mode 100644 container-search/src/main/java/com/yahoo/prelude/templates/FormattingOptions.java delete mode 100644 container-search/src/main/java/com/yahoo/prelude/templates/GenericTemplateSet.java delete mode 100644 container-search/src/main/java/com/yahoo/prelude/templates/HitContext.java delete mode 100644 container-search/src/main/java/com/yahoo/prelude/templates/LogExceptionUserTemplateDelegator.java delete mode 100644 container-search/src/main/java/com/yahoo/prelude/templates/MapContext.java delete mode 100644 container-search/src/main/java/com/yahoo/prelude/templates/PageTemplateSet.java delete mode 100644 container-search/src/main/java/com/yahoo/prelude/templates/SearchRendererAdaptor.java delete mode 100644 container-search/src/main/java/com/yahoo/prelude/templates/Template.java delete mode 100644 container-search/src/main/java/com/yahoo/prelude/templates/TemplateSet.java delete mode 100644 container-search/src/main/java/com/yahoo/prelude/templates/TiledTemplateSet.java delete mode 100644 container-search/src/main/java/com/yahoo/prelude/templates/UserTemplate.java delete mode 100644 container-search/src/main/java/com/yahoo/prelude/templates/package-info.java delete mode 100644 container-search/src/main/java/com/yahoo/search/result/Templating.java delete mode 100644 container-search/src/test/java/com/yahoo/prelude/templates/test/BoomTemplate.java delete mode 100644 container-search/src/test/java/com/yahoo/prelude/templates/test/GroupedResultTestCase.java delete mode 100644 container-search/src/test/java/com/yahoo/prelude/templates/test/HitContextTestCase.java delete mode 100644 container-search/src/test/java/com/yahoo/prelude/templates/test/TemplateTestCase.java delete mode 100644 container-search/src/test/java/com/yahoo/prelude/templates/test/TestTemplate.java delete mode 100644 container-search/src/test/java/com/yahoo/prelude/templates/test/templates/asearch/error.templ delete mode 100644 container-search/src/test/java/com/yahoo/prelude/templates/test/templates/asearch/footer.templ delete mode 100644 container-search/src/test/java/com/yahoo/prelude/templates/test/templates/asearch/header.templ delete mode 100644 container-search/src/test/java/com/yahoo/prelude/templates/test/templates/asearch/hit.templ delete mode 100644 container-search/src/test/java/com/yahoo/prelude/templates/test/templates/asearch/nohits.templ delete mode 100644 container-search/src/test/java/com/yahoo/prelude/templates/test/templates/cgi-bin/asearch/error.templ delete mode 100644 container-search/src/test/java/com/yahoo/prelude/templates/test/templates/cgi-bin/asearch/footer.templ delete mode 100644 container-search/src/test/java/com/yahoo/prelude/templates/test/templates/cgi-bin/asearch/header.templ delete mode 100644 container-search/src/test/java/com/yahoo/prelude/templates/test/templates/cgi-bin/asearch/hit.templ delete mode 100644 container-search/src/test/java/com/yahoo/prelude/templates/test/templates/cgi-bin/asearch/nohits.templ delete mode 100644 container-search/src/test/java/com/yahoo/prelude/templates/test/templates/xsearch/error.templ delete mode 100644 container-search/src/test/java/com/yahoo/prelude/templates/test/templates/xsearch/footer.templ delete mode 100644 container-search/src/test/java/com/yahoo/prelude/templates/test/templates/xsearch/header.templ delete mode 100644 container-search/src/test/java/com/yahoo/prelude/templates/test/templates/xsearch/hit.templ delete mode 100644 container-search/src/test/java/com/yahoo/prelude/templates/test/templates/xsearch/nohits.templ delete mode 100644 container-search/src/test/java/com/yahoo/prelude/templates/test/tilingexample.xml delete mode 100644 container-search/src/test/java/com/yahoo/prelude/templates/test/tilingexample2.xml delete mode 100644 container-search/src/test/java/com/yahoo/search/result/TemplatingTestCase.java (limited to 'container-search/src') 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 secondary 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); - - /** - *

Returns a value by looking it up in the primary, - * and thereafter in secondary sources.

- * - *

If xml escaping is on and this is a string, xml attribute escaping is done - *

- */ - abstract public Object get(String key); - - /** - * Removes a secondary 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 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; - -/** - *

A template set which provides XML rendering of results and hits.

- * - *

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.

- * - * @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 { - - 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 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.
- * 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.
- * 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> 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 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 fieldsAsAttributes = new LinkedHashMap<>(); - - private Map fieldsWithSubtypes = new LinkedHashMap<>(); - private Map prefixedFieldsWithSubtypes = new LinkedHashMap<>(); - - private Set fieldsNotRendered = new LinkedHashSet<>(); - private Set 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: - *
-	 *  <hit latency="100"></hit>
-	 *  
- * instead of: - *
-	 *  <hit><latency>100</latency></hit>
-	 *  
- */ - public void formatFieldAsAttribute(String fieldName, String attributeName) { - fieldsAsAttributes.put(fieldName, attributeName); - } - - public Set> 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: - *
-	 * <latency type="connect">50</latency>
-	 * <latency type="finish">250</latency>
-	 * 
- * Instead of: - *
-	 * <hit>
-	 *   <latency-connect>50</latency-connect>
-	 *   <latency-finish>50</latency-finish>
-	 * 
- */ - 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: - *
-	 * <latency type="connect">50</latency>
-	 * <latency type="finish">250</latency>
-	 * 
- * Instead of: - *
-	 * <hit>
-	 *   <latency-connect>50</latency-connect>
-	 *   <latency-finish>50</latency-finish>
-	 * 
- * - * 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 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. - * - *

- * 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. - * - *

- * 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> 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 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 template) { - templates.put(templateName,template); - } - - /** - * Sets the selected template - * - * @throws NullPointerException if the given template is null - */ - public void setTemplateNotNull(String templateName, Template 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 getKeys() { - Set 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 extends UserTemplate { - - private static Logger log = Logger.getLogger(LogExceptionUserTemplateDelegator.class.getName()); - private final UserTemplate delegate; - - public LogExceptionUserTemplateDelegator(UserTemplate 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 getTemplate(String templateName) { - throw new UnsupportedOperationException(); - } - - @Override - public void setTemplate(String templateName, Template template) { - throw new UnsupportedOperationException(); - } - - @Override - public void setTemplateNotNull(String templateName, Template template) { - throw new UnsupportedOperationException(); - } - - /*** Template - - @Override - public void (Context context, T writer) throws IOException { - try { - delegate.(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 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 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 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 Collection all(Collection collection, T extra) { - Collection 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 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 { - - /** - * 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; - -/** - *

A template set contains instances of the various templates - * required to render a result.

- * - *

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.

- * - * @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 extends UserTemplate { - - 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 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 getHeader(Result result) { return (Template) 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 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 getFooter(Result result) { return (Template) 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 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 getNohits(Result result) { return (Template) getTemplate("nohits"); } - - - /** - * @return the template for rendering the query context, never null - */ - @SuppressWarnings("unchecked") - public Template getQueryContext(Result result) { - return (Template) getTemplate(queryContextTemplateName); - } - - /** - * @param template The template to be used for rendering query contexts, never null. - */ - public void setQueryContext(Template 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 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 getError(Result result) { return (Template) 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 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 getHit(Hit resultHit) { return (Template) 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 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 getHitFooter(Hit hit) { return (Template) 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 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: - *
    - *
  • As hit fields are rendered as XML tag names, their name must be compatible with XML tag names.
  • - *
  • 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.
  • - *
  • 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.
  • - *
- * - *

Hit types required for proper rendering

- * - * - * - * - * - *
XML tag pathRequired hit type
/result/sectionA hit group and have a "section" type
/result/metaA hit group and have a "meta" type
/result/meta/providerA hit that has a "logging" type
- * - *

Provider fields formatting options

- * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
FieldFormattingField type
providername attribute of <provider> tagProvided by container
schemescheme attribute of <provider> tagProvided by container
hosthost attribute of <provider> tagProvided by container
portport attribute of <provider> tagProvided by container
pathpath attribute of <provider> tagProvided by container
statusresult attribute of <provider> tagProvided by container
latency_connect<latency type="connect"> tagProvided by container
latency_start<latency type="start"> tagProvided by container
latency_finish<latency type="finish"> tagProvided by container
query_param_*<parameter name="..."> tagProvided by container
header_*<header name="..."> tagProvided by container
response_header_*<response-header name="..."> tagProvided by container
count_first<count type="first"> tagProvided by container
count_last<count type="last"> tagProvided by container
count_total<count type="total"> tagProvided by container
count_deep<count type="deep"> tagProvided by container
queryattrs_xorronum<queryattrs name="xorronum"> tagProvided by YST searcher
queryattrs_RankFeaturesRewriterAttr<queryattrs name="RankFeaturesRewriterAttr"> tagProvided by YST searcher
queryattrs_intlannotator<queryattrs name="intlannotator"> tagProvided by YST searcher
queryattrs_category<queryattrs name="category"> tagProvided by YST searcher
wordcounts_*<wordcounts word="..."> tagProvided by YST searcher
- * - * @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 - 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 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 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> it = hit.fieldIterator(); it.hasNext(); ) { - Map.Entry 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 parameters,XMLWriter writer) throws IOException { - // Render content - for (Map.Entry 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 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> it = hit.fieldIterator(); it.hasNext(); ) { - Map.Entry 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 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. - * - *

- * 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 extends GenericTemplateSet { - - // & - private static final byte[] ampersand = new byte[] { 38, 97, 109, 112, 59 }; - - // < - private static final byte[] lessThan = new byte[] { 38, 108, 116, 59 }; - // > - 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. - * - *

- * 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. - * - *

- * 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. - * - *

- * 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. - * - *

- * 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. - * - *

- * 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. - * - *

- * 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. - * - *

- * 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. - * - *

- * 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. - * - *

- * 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; diff --git a/container-search/src/main/java/com/yahoo/search/Result.java b/container-search/src/main/java/com/yahoo/search/Result.java index e70916369a3..364e60e6263 100644 --- a/container-search/src/main/java/com/yahoo/search/Result.java +++ b/container-search/src/main/java/com/yahoo/search/Result.java @@ -48,11 +48,6 @@ public final class Result extends com.yahoo.processing.Response implements Clone */ private ListMap headers = null; - /** - * Result rendering infrastructure. - */ - private final Templating templating; - /** Creates a new Result where the top level hit group has id "toplevel" */ public Result(Query query) { this(query, new HitGroup("toplevel")); @@ -75,7 +70,6 @@ public final class Result extends com.yahoo.processing.Response implements Clone if (query.getRanking().getSorting() != null) { setHitOrderer(new HitSortOrderer(query.getRanking().getSorting())); } - templating = new Templating(this); } /** Create a result containing an error */ @@ -92,8 +86,6 @@ public final class Result extends com.yahoo.processing.Response implements Clone */ @SuppressWarnings("deprecation") public void mergeWith(Result result) { - if (templating.usesDefaultTemplate()) - templating.setRenderer(result.templating.getRenderer()); totalHitCount += result.getTotalHitCount(); deepHitCount += result.getDeepHitCount(); timeAccountant.merge(result.getElapsedTime()); @@ -228,7 +220,6 @@ public final class Result extends com.yahoo.processing.Response implements Clone resultClone.hits = hits.clone(); - resultClone.getTemplating().setRenderer(null); // TODO: Remove on Vespa 7 resultClone.setElapsedTime(new ElapsedTime()); return resultClone; } @@ -299,9 +290,7 @@ public final class Result extends com.yahoo.processing.Response implements Clone * @param hit * the hit to be analyzed */ - protected void traceExtraHitProperties(StringBuilder hitBuffer, Hit hit) { - return; - } + protected void traceExtraHitProperties(StringBuilder hitBuffer, Hit hit) { } /** Returns the context of this result - this is equal to getQuery().getContext(create) */ public QueryContext getContext(boolean create) { return getQuery().getContext(create); } @@ -337,17 +326,4 @@ public final class Result extends com.yahoo.processing.Response implements Clone return headers; } - /** - * The Templating object contains helper methods and data containers for - * result rendering. - * - * @return helper object for result rendering - * @deprecated use renderers - */ - // TODO: Remove on Vespa 7 - @Deprecated// OK (But wait for deprecated handlers in vespaclient-container-plugin to be removed) - public Templating getTemplating() { - return templating; - } - } diff --git a/container-search/src/main/java/com/yahoo/search/handler/SearchHandler.java b/container-search/src/main/java/com/yahoo/search/handler/SearchHandler.java index d5c4d3b2d11..d2490ec9532 100644 --- a/container-search/src/main/java/com/yahoo/search/handler/SearchHandler.java +++ b/container-search/src/main/java/com/yahoo/search/handler/SearchHandler.java @@ -220,8 +220,6 @@ public class SearchHandler extends LoggingRequestHandler { Result result = new Result(query, errorMessage); Renderer renderer = getRendererCopy(ComponentSpecification.fromString(request.getProperty("format"))); - result.getTemplating().setRenderer(renderer); // Pre-Vespa 6 Result.getEncoding() expects this TODO: Remove opn Vespa 7 - return new HttpSearchResponse(getHttpResponseStatus(request, result), result, query, renderer); } @@ -282,17 +280,9 @@ public class SearchHandler extends LoggingRequestHandler { result = search(pathAndQuery, query, searchChain, searchChainRegistry); } - Renderer renderer; - if (result.getTemplating().usesDefaultTemplate()) { // TODO: Remove on Vespa 7 - renderer = toRendererCopy(query.getPresentation().getRenderer()); - result.getTemplating().setRenderer(renderer); // pre-Vespa 6 Result.getEncoding() expects this to be set. - } - else { // somebody explicitly assigned a old style template // TODO: Remove on Vespa 7 - renderer = perRenderingCopy(result.getTemplating().getRenderer()); - } - // Transform result to response - HttpSearchResponse response = new HttpSearchResponse(getHttpResponseStatus(request, result), + Renderer renderer = toRendererCopy(query.getPresentation().getRenderer()); + HttpSearchResponse response = new HttpSearchResponse(getHttpResponseStatus(request, result), result, query, renderer); if (hostResponseHeaderKey.isPresent()) response.headers().add(hostResponseHeaderKey.get(), selfHostname); @@ -351,9 +341,6 @@ public class SearchHandler extends LoggingRequestHandler { } Result result = execution.search(query); - if (result.getTemplating() == null) // TODO: Remove on Vespa 7 - result.getTemplating().setRenderer(renderer); - ensureQuerySet(result, query); execution.fill(result, result.getQuery().getPresentation().getSummary()); diff --git a/container-search/src/main/java/com/yahoo/search/rendering/RendererRegistry.java b/container-search/src/main/java/com/yahoo/search/rendering/RendererRegistry.java index 45d0d6f000c..cacee87288e 100644 --- a/container-search/src/main/java/com/yahoo/search/rendering/RendererRegistry.java +++ b/container-search/src/main/java/com/yahoo/search/rendering/RendererRegistry.java @@ -4,10 +4,6 @@ package com.yahoo.search.rendering; import com.yahoo.component.ComponentId; import com.yahoo.component.ComponentSpecification; import com.yahoo.component.provider.ComponentRegistry; -import com.yahoo.prelude.templates.PageTemplateSet; -import com.yahoo.prelude.templates.SearchRendererAdaptor; -import com.yahoo.prelude.templates.TiledTemplateSet; -import com.yahoo.prelude.templates.UserTemplate; import com.yahoo.processing.rendering.Renderer; import com.yahoo.search.Result; @@ -27,9 +23,6 @@ public final class RendererRegistry extends ComponentRegistry templateSet) { - Renderer renderer = new SearchRendererAdaptor(templateSet); - ComponentId rendererId = new ComponentId(templateSet.getName()); - renderer.initId(rendererId); - register(rendererId, renderer); - return rendererId; } /** diff --git a/container-search/src/main/java/com/yahoo/search/result/Templating.java b/container-search/src/main/java/com/yahoo/search/result/Templating.java deleted file mode 100644 index a8b1eedf528..00000000000 --- a/container-search/src/main/java/com/yahoo/search/result/Templating.java +++ /dev/null @@ -1,215 +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.search.result; - -import java.util.Map; - -import com.yahoo.container.jdisc.HttpRequest; -import com.yahoo.prelude.templates.SearchRendererAdaptor; -import com.yahoo.prelude.templates.TemplateSet; -import com.yahoo.prelude.templates.UserTemplate; -import com.yahoo.processing.rendering.Renderer; -import com.yahoo.search.Result; -import com.yahoo.search.query.Presentation; - -/** - * Helper methods and data store for result attributes geared towards result - * rendering and presentation. - * - * @author Steinar Knutsen - * @deprecated do not use - */ -@Deprecated // OK (But wait for deprecated handlers in vespaclient-container-plugin to be removed) -// TODO: Remove on Vespa 7 -public class Templating { - - private final Result result; - private Renderer renderer; - - public Templating(Result result) { - super(); - this.result = result; - } - - /** - * Returns The first hit presented in the result as an index into the global - * list of all hits generated by the user query. - */ - public int getFirstHitNo() { - return result.getQuery().getOffset() + 1; - } - - /** - * Returns the first hit of the next result page, 0 if there aren't any more - * hits available - */ - public long getNextFirstHitNo() { - if (result.getQuery().getHits() > result.getConcreteHitCount()) { - return 0; - } - - return Math.min(getLastHitNo() + 1, result.getTotalHitCount()); - } - - /** - * Returns the first hit of the next result page, 0 if there aren't any more - * hits available - */ - public long getNextLastHitNo() { - if (result.getQuery().getHits() > result.getConcreteHitCount()) { - return 0; - } - - return Math.min(getLastHitNo() + result.getConcreteHitCount(), result.getTotalHitCount()); - } - - /** - * Returns the number of the last result of the current hit page. - */ - public int getLastHitNo() { - return getFirstHitNo() + result.getConcreteHitCount() - 1; - } - - /** - * The first hit presented on the previous result page as an index into the - * global list of all hits generated by the user query - */ - public int getPrevFirstHitNo() { - return Math.max(getFirstHitNo() - result.getQuery().getHits(), 1); - } - - /** - * The last hit presented on the previous result page as an index into the - * global list of all hits generated by the user query - */ - public int getPrevLastHitNo() { - return Math.max(getFirstHitNo() - 1, 0); - } - - /** - * An URL that may be used to obtain the next result page. - */ - public String getNextResultURL() { - HttpRequest request = result.getQuery().getHttpRequest(); - StringBuilder nextURL = new StringBuilder(); - - nextURL.append(getPath(request)).append("?"); - parametersExceptOffset(request, nextURL); - - int offset = getLastHitNo(); - - nextURL.append("&").append("offset=").append(Integer.toString(offset)); - return nextURL.toString(); - } - - /** - * An URL that may be used to obtain the previous result page. - */ - public String getPreviousResultURL() { - HttpRequest request = result.getQuery().getHttpRequest(); - StringBuilder prevURL = new StringBuilder(); - - prevURL.append(getPath(request)).append("?"); - parametersExceptOffset(request, prevURL); - int offset = getPrevFirstHitNo() - 1; - prevURL.append("&").append("offset=").append(Integer.toString(offset)); - return prevURL.toString(); - } - - public String getCurrentResultURL() { - HttpRequest request = result.getQuery().getHttpRequest(); - StringBuilder thisURL = new StringBuilder(); - - thisURL.append(getPath(request)).append("?"); - parameters(request, thisURL); - return thisURL.toString(); - } - - private String getPath(HttpRequest request) { - String path = request.getUri().getPath(); - if (path == null) { - path = ""; - } - return path; - } - - private void parametersExceptOffset(HttpRequest request, StringBuilder nextURL) { - int startLength = nextURL.length(); - for (Map.Entry property : request.propertyMap().entrySet()) { - if (property.getKey().equals("offset")) continue; - - if (nextURL.length() > startLength) - nextURL.append("&"); - nextURL.append(property.getKey()).append("=").append(property.getValue()); - } - } - - private void parameters(HttpRequest request, StringBuilder nextURL) { - int startLength = nextURL.length(); - for (Map.Entry property : request.propertyMap().entrySet()) { - if (nextURL.length() > startLength) - nextURL.append("&"); - nextURL.append(property.getKey()).append("=").append(property.getValue()); - } - } - - /** - * Returns the templates which will render the result. This is never null. - * If default rendering is used, it is a TemplateSet containing no - * templates. - * - * @deprecated use a renderer instead - */ - @SuppressWarnings("rawtypes") - // TODO: Remove on Vespa 7 - @Deprecated // OK - public UserTemplate getTemplates() { - if (renderer == null) { - return TemplateSet.getDefault(); - } else if (renderer instanceof SearchRendererAdaptor) { - return ((SearchRendererAdaptor) renderer).getAdaptee(); - } else { - throw new RuntimeException( - "Please use getTemplate() instead of getTemplates() when using the new template api."); - } - } - - /** - * Sets the template set which should render this result set - * - * @param templates - * the templates which should render this result, or null to - * use the default xml rendering - */ - @SuppressWarnings("deprecation") - public void setTemplates(@SuppressWarnings("rawtypes") UserTemplate templates) { - if (templates == null) { - setTemplates(TemplateSet.getDefault()); - } else { - setRenderer(new SearchRendererAdaptor(templates)); - } - } - - /** - * @deprecated since 5.1.21, use {@link Presentation#getRenderer()} - */ - public Renderer getRenderer() { - return renderer; - } - - /** - * @deprecated since 5.1.21, use {@link Presentation#setRenderer(com.yahoo.component.ComponentSpecification)} - */ - public void setRenderer(Renderer renderer) { - this.renderer = renderer; - } - - /** - * For internal use only. - */ - public boolean usesDefaultTemplate() { - return renderer == null || - (renderer instanceof SearchRendererAdaptor && - ((SearchRendererAdaptor) renderer).getAdaptee().isDefaultTemplateSet()); - } - -} diff --git a/container-search/src/test/java/com/yahoo/prelude/templates/test/BoomTemplate.java b/container-search/src/test/java/com/yahoo/prelude/templates/test/BoomTemplate.java deleted file mode 100644 index 0bbc5151b40..00000000000 --- a/container-search/src/test/java/com/yahoo/prelude/templates/test/BoomTemplate.java +++ /dev/null @@ -1,51 +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.test; - -import java.io.IOException; -import java.io.Writer; - -import com.yahoo.prelude.templates.Context; -import com.yahoo.prelude.templates.UserTemplate; - -/** - * Test template which throws a runtime exception in its footer. - * - * @author Steinar Knutsen - */ -@SuppressWarnings("rawtypes") -public class BoomTemplate extends UserTemplate { - public BoomTemplate(String name, String mimeType, String encoding) { - super(name, mimeType, encoding); - } - - @Override - public void error(Context context, Writer writer) throws IOException { - // NOP - } - - @Override - public void footer(Context context, Writer writer) throws IOException { - throw new RuntimeException("Boom!"); - } - - @Override - public void header(Context context, Writer writer) throws IOException { - writer.write("header"); - } - - @Override - public void hit(Context context, Writer writer) throws IOException { - // NOP - } - - @Override - public void hitFooter(Context context, Writer writer) throws IOException { - // NOP - } - - @Override - public void noHits(Context context, Writer writer) throws IOException { - // NOP - } - -} diff --git a/container-search/src/test/java/com/yahoo/prelude/templates/test/GroupedResultTestCase.java b/container-search/src/test/java/com/yahoo/prelude/templates/test/GroupedResultTestCase.java deleted file mode 100644 index 07d5dcc9e2d..00000000000 --- a/container-search/src/test/java/com/yahoo/prelude/templates/test/GroupedResultTestCase.java +++ /dev/null @@ -1,71 +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.test; - -import com.yahoo.search.Query; -import com.yahoo.search.Result; -import com.yahoo.search.result.Hit; -import com.yahoo.search.result.HitGroup; -import org.junit.Test; - -import static org.junit.Assert.assertEquals; - -/** - * Tests composition of grouped results using the HitGroup class - * - * @author bratseth - */ -public class GroupedResultTestCase { - - @Test - public void testGroupedResult() { - Result result=new Result(new Query("?query=foo")); - HitGroup hitGroup1=new HitGroup("group1",300); - hitGroup1.add(new Hit("group1.1",200)); - HitGroup hitGroup2=new HitGroup("group2",600); - Hit topLevelHit1=new Hit("toplevel.1",500); - Hit topLevelHit2=new Hit("toplevel.2",700); - result.hits().add(hitGroup1); - result.hits().add(topLevelHit1); - result.hits().add(hitGroup2); - result.hits().add(topLevelHit2); - hitGroup1.add(new Hit("group1.2",800)); - hitGroup2.add(new Hit("group2.1",800)); - hitGroup2.add(new Hit("group2.2",300)); - hitGroup2.add(new Hit("group2.3",500)); - - // Should have 7 concrete hits, ordered as - // toplevel.2 - // group2 - // group2.1 - // group2.3 - // group2.2 - // toplevel.1 - // group1 - // group1.2 - // group1.1 - // Assert this: - - assertEquals(7,result.getConcreteHitCount()); - assertEquals(4,result.getHitCount()); - - Hit topLevel2=result.hits().get(0); - assertEquals("toplevel.2",topLevel2.getId().stringValue()); - - HitGroup returnedGroup2=(HitGroup)result.hits().get(1); - assertEquals(3,returnedGroup2.getConcreteSize()); - assertEquals(3,returnedGroup2.size()); - assertEquals("group2.1",returnedGroup2.get(0).getId().stringValue()); - assertEquals("group2.3",returnedGroup2.get(1).getId().stringValue()); - assertEquals("group2.2",returnedGroup2.get(2).getId().stringValue()); - - Hit topLevel1=result.hits().get(2); - assertEquals("toplevel.1",topLevel1.getId().stringValue()); - - HitGroup returnedGroup1=(HitGroup)result.hits().get(3); - assertEquals(2,returnedGroup1.getConcreteSize()); - assertEquals(2,returnedGroup1.size()); - assertEquals("group1.2",returnedGroup1.get(0).getId().stringValue()); - assertEquals("group1.1",returnedGroup1.get(1).getId().stringValue()); - } - -} diff --git a/container-search/src/test/java/com/yahoo/prelude/templates/test/HitContextTestCase.java b/container-search/src/test/java/com/yahoo/prelude/templates/test/HitContextTestCase.java deleted file mode 100644 index 6ff8c2f9d6c..00000000000 --- a/container-search/src/test/java/com/yahoo/prelude/templates/test/HitContextTestCase.java +++ /dev/null @@ -1,26 +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.test; - -import static org.junit.Assert.assertEquals; - -import java.lang.reflect.Method; -import java.util.List; - -import org.junit.Test; - -import com.yahoo.prelude.templates.HitContext; -import com.yahoo.protect.ClassValidator; - -/** - * Check the entire Context class is correctly masked. - * - * @author Steinar Knutsen - */ -public class HitContextTestCase { - - @Test - public void checkMethods() { - List unmasked = ClassValidator.unmaskedMethodsFromSuperclass(HitContext.class); - assertEquals("Unmasked methods from superclass: " + unmasked, 0, unmasked.size()); - } -} diff --git a/container-search/src/test/java/com/yahoo/prelude/templates/test/TemplateTestCase.java b/container-search/src/test/java/com/yahoo/prelude/templates/test/TemplateTestCase.java deleted file mode 100644 index 6f49ebbdee0..00000000000 --- a/container-search/src/test/java/com/yahoo/prelude/templates/test/TemplateTestCase.java +++ /dev/null @@ -1,55 +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.test; - -import java.io.ByteArrayOutputStream; -import java.nio.charset.Charset; -import java.nio.charset.CharsetEncoder; - -import com.yahoo.io.ByteWriter; -import com.yahoo.prelude.templates.UserTemplate; -import org.junit.Test; - -import static org.junit.Assert.assertEquals; - -/** - * @author Steinar Knutsen - */ -public class TemplateTestCase { - - private CharsetEncoder encoder; - private ByteArrayOutputStream stream; - - public TemplateTestCase () { - Charset cs = Charset.forName("UTF-8"); - encoder = cs.newEncoder(); - stream = new ByteArrayOutputStream(); - } - - @Test - public void testASCIIQuoting() throws java.io.IOException { - stream.reset(); - byte[] c = new byte[] { 97, 98, 99, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 }; - ByteWriter bw = new ByteWriter(stream, encoder); - UserTemplate.dumpAndXMLQuoteUTF8(bw, c); - bw.close(); - String res = stream.toString("UTF-8"); - String correct = "abc\\u0000\\u0001\\u0002\\u0003\\u0004\\u0005\\u0006\\u0007\\u0008\t\n\\u000B\\u000C\r\\u000E\\u000F\\u0010\\u0011"; - assertEquals(correct, res); - - } - - @Test - public void testXMLQuoting() throws java.io.IOException { - stream.reset(); - // c = > - byte[] c = new byte[] { 60, 115, 62, 38, 103, 116, 59 }; - ByteWriter bw = new ByteWriter(stream, encoder); - UserTemplate.dumpAndXMLQuoteUTF8(bw, c); - bw.close(); - String res = stream.toString("UTF-8"); - String correct = "<s>&gt;"; - assertEquals(correct, res); - - } - -} diff --git a/container-search/src/test/java/com/yahoo/prelude/templates/test/TestTemplate.java b/container-search/src/test/java/com/yahoo/prelude/templates/test/TestTemplate.java deleted file mode 100644 index 0f5e126dae8..00000000000 --- a/container-search/src/test/java/com/yahoo/prelude/templates/test/TestTemplate.java +++ /dev/null @@ -1,53 +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.test; - -import java.io.IOException; -import java.io.Writer; - -import com.yahoo.prelude.templates.Context; -import com.yahoo.prelude.templates.UserTemplate; - -/** - * Test basic UserTemplate functionality of detecting - * overridden group rendering methods. - * - * @author Steinar Knutsen - */ -@SuppressWarnings("rawtypes") -public class TestTemplate extends UserTemplate { - - public TestTemplate(String name, String mimeType, String encoding) { - super(name, mimeType, encoding); - } - - @Override - public void error(Context context, Writer writer) throws IOException { - // NOP - } - - @Override - public void footer(Context context, Writer writer) throws IOException { - // NOP - } - - @Override - public void header(Context context, Writer writer) throws IOException { - // NOP - } - - @Override - public void hit(Context context, Writer writer) throws IOException { - // NOP - } - - @Override - public void hitFooter(Context context, Writer writer) throws IOException { - // NOP - } - - @Override - public void noHits(Context context, Writer writer) throws IOException { - // NOP - } - -} diff --git a/container-search/src/test/java/com/yahoo/prelude/templates/test/templates/asearch/error.templ b/container-search/src/test/java/com/yahoo/prelude/templates/test/templates/asearch/error.templ deleted file mode 100644 index 4e7a9379b73..00000000000 --- a/container-search/src/test/java/com/yahoo/prelude/templates/test/templates/asearch/error.templ +++ /dev/null @@ -1 +0,0 @@ -### Result diff --git a/container-search/src/test/java/com/yahoo/prelude/templates/test/templates/asearch/footer.templ b/container-search/src/test/java/com/yahoo/prelude/templates/test/templates/asearch/footer.templ deleted file mode 100644 index 4e7a9379b73..00000000000 --- a/container-search/src/test/java/com/yahoo/prelude/templates/test/templates/asearch/footer.templ +++ /dev/null @@ -1 +0,0 @@ -### Result diff --git a/container-search/src/test/java/com/yahoo/prelude/templates/test/templates/asearch/header.templ b/container-search/src/test/java/com/yahoo/prelude/templates/test/templates/asearch/header.templ deleted file mode 100644 index 4e7a9379b73..00000000000 --- a/container-search/src/test/java/com/yahoo/prelude/templates/test/templates/asearch/header.templ +++ /dev/null @@ -1 +0,0 @@ -### Result diff --git a/container-search/src/test/java/com/yahoo/prelude/templates/test/templates/asearch/hit.templ b/container-search/src/test/java/com/yahoo/prelude/templates/test/templates/asearch/hit.templ deleted file mode 100644 index 4e7a9379b73..00000000000 --- a/container-search/src/test/java/com/yahoo/prelude/templates/test/templates/asearch/hit.templ +++ /dev/null @@ -1 +0,0 @@ -### Result diff --git a/container-search/src/test/java/com/yahoo/prelude/templates/test/templates/asearch/nohits.templ b/container-search/src/test/java/com/yahoo/prelude/templates/test/templates/asearch/nohits.templ deleted file mode 100644 index 4e7a9379b73..00000000000 --- a/container-search/src/test/java/com/yahoo/prelude/templates/test/templates/asearch/nohits.templ +++ /dev/null @@ -1 +0,0 @@ -### Result diff --git a/container-search/src/test/java/com/yahoo/prelude/templates/test/templates/cgi-bin/asearch/error.templ b/container-search/src/test/java/com/yahoo/prelude/templates/test/templates/cgi-bin/asearch/error.templ deleted file mode 100644 index 4e7a9379b73..00000000000 --- a/container-search/src/test/java/com/yahoo/prelude/templates/test/templates/cgi-bin/asearch/error.templ +++ /dev/null @@ -1 +0,0 @@ -### Result diff --git a/container-search/src/test/java/com/yahoo/prelude/templates/test/templates/cgi-bin/asearch/footer.templ b/container-search/src/test/java/com/yahoo/prelude/templates/test/templates/cgi-bin/asearch/footer.templ deleted file mode 100644 index 4e7a9379b73..00000000000 --- a/container-search/src/test/java/com/yahoo/prelude/templates/test/templates/cgi-bin/asearch/footer.templ +++ /dev/null @@ -1 +0,0 @@ -### Result diff --git a/container-search/src/test/java/com/yahoo/prelude/templates/test/templates/cgi-bin/asearch/header.templ b/container-search/src/test/java/com/yahoo/prelude/templates/test/templates/cgi-bin/asearch/header.templ deleted file mode 100644 index 4e7a9379b73..00000000000 --- a/container-search/src/test/java/com/yahoo/prelude/templates/test/templates/cgi-bin/asearch/header.templ +++ /dev/null @@ -1 +0,0 @@ -### Result diff --git a/container-search/src/test/java/com/yahoo/prelude/templates/test/templates/cgi-bin/asearch/hit.templ b/container-search/src/test/java/com/yahoo/prelude/templates/test/templates/cgi-bin/asearch/hit.templ deleted file mode 100644 index 4e7a9379b73..00000000000 --- a/container-search/src/test/java/com/yahoo/prelude/templates/test/templates/cgi-bin/asearch/hit.templ +++ /dev/null @@ -1 +0,0 @@ -### Result diff --git a/container-search/src/test/java/com/yahoo/prelude/templates/test/templates/cgi-bin/asearch/nohits.templ b/container-search/src/test/java/com/yahoo/prelude/templates/test/templates/cgi-bin/asearch/nohits.templ deleted file mode 100644 index 4e7a9379b73..00000000000 --- a/container-search/src/test/java/com/yahoo/prelude/templates/test/templates/cgi-bin/asearch/nohits.templ +++ /dev/null @@ -1 +0,0 @@ -### Result diff --git a/container-search/src/test/java/com/yahoo/prelude/templates/test/templates/xsearch/error.templ b/container-search/src/test/java/com/yahoo/prelude/templates/test/templates/xsearch/error.templ deleted file mode 100644 index ca186b86259..00000000000 --- a/container-search/src/test/java/com/yahoo/prelude/templates/test/templates/xsearch/error.templ +++ /dev/null @@ -1 +0,0 @@ -$result.error.message diff --git a/container-search/src/test/java/com/yahoo/prelude/templates/test/templates/xsearch/footer.templ b/container-search/src/test/java/com/yahoo/prelude/templates/test/templates/xsearch/footer.templ deleted file mode 100644 index 07a5dd6a881..00000000000 --- a/container-search/src/test/java/com/yahoo/prelude/templates/test/templates/xsearch/footer.templ +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/container-search/src/test/java/com/yahoo/prelude/templates/test/templates/xsearch/header.templ b/container-search/src/test/java/com/yahoo/prelude/templates/test/templates/xsearch/header.templ deleted file mode 100644 index 8e3a001545d..00000000000 --- a/container-search/src/test/java/com/yahoo/prelude/templates/test/templates/xsearch/header.templ +++ /dev/null @@ -1,2 +0,0 @@ - - diff --git a/container-search/src/test/java/com/yahoo/prelude/templates/test/templates/xsearch/hit.templ b/container-search/src/test/java/com/yahoo/prelude/templates/test/templates/xsearch/hit.templ deleted file mode 100644 index 428a2f15ef5..00000000000 --- a/container-search/src/test/java/com/yahoo/prelude/templates/test/templates/xsearch/hit.templ +++ /dev/null @@ -1,5 +0,0 @@ - -$uri -$category -$bsumtitle - diff --git a/container-search/src/test/java/com/yahoo/prelude/templates/test/templates/xsearch/nohits.templ b/container-search/src/test/java/com/yahoo/prelude/templates/test/templates/xsearch/nohits.templ deleted file mode 100644 index d466f0bb7d2..00000000000 --- a/container-search/src/test/java/com/yahoo/prelude/templates/test/templates/xsearch/nohits.templ +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/container-search/src/test/java/com/yahoo/prelude/templates/test/tilingexample.xml b/container-search/src/test/java/com/yahoo/prelude/templates/test/tilingexample.xml deleted file mode 100644 index ea5d56d2b31..00000000000 --- a/container-search/src/test/java/com/yahoo/prelude/templates/test/tilingexample.xml +++ /dev/null @@ -1,65 +0,0 @@ - - - - -

- - - - http://www.hotels.com/ - Cheap <hi>hotels</hi> - Low Rates Guaranteed. Call a Hotel Expert. - - - http://www.expedia.com/ - Cheap <hi>hotels</hi> at Expedia - Expedia Special Rates Means We Guarantee Our Low Rates on Rooms. - - - - - www.hotels.com - Hotels.com | Cheap Hotels | Discount Hotel Rooms | Motels | Lodging - Hotels.com helps you find great rates on hotels and discount hotel packages. - - - www.indigohotels.com - Hotel Indigo Hotels United States - Official Web Site - Make Hotel Indigo online hotel reservations and book your hotel rooms today. - - - www.all-hotels.com - All hotels - Online hotel directory and reservations. - - - - - www.daysinn.com - Days Inn Special Deal - Buy now and Save 15% Off Our Best Available Rate with Days Inn. - - - http://www.expedia.com/ - Cheap <hi>hotels</hi> at Expedia - Expedia Special Rates Means We Guarantee Our Low Rates on Rooms. - - -
- -
- - - www.daysinn.com - Days Inn Special Deal - Buy now and Save 15% Off Our Best Available Rate with Days Inn. - - - www.holidayinn.com - Holiday Inn: Official Site - Book with Holiday Inn. Free Internet. Kids eat free. - - -
- - diff --git a/container-search/src/test/java/com/yahoo/prelude/templates/test/tilingexample2.xml b/container-search/src/test/java/com/yahoo/prelude/templates/test/tilingexample2.xml deleted file mode 100644 index 2e936b0015a..00000000000 --- a/container-search/src/test/java/com/yahoo/prelude/templates/test/tilingexample2.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - -
- - - 159 - Yahoo - - -
- - - - com.yahoo.search.federation.yst.YSTBackendSearcherproxy-tw1cache.idp.inktomisearch.com55556/search - http://proxy-tw1cache.idp.inktomisearch.com:55556/search?qp=yahootw-twp&Fields=url%2Credirecturl%2Cdate%2Csize%2Cformat%2Csms_product%2Ccacheurl%2Cnodename%2Cid%2Clanguage%2Crsslinks%2Crssvalidatedlinks%2Ccpc%2Cclustertype%2Cxml.active_abstract%2Cactive_abstract_type%2Cactive_abstract_source%2Ccontract_id%2Ctranslated%2Cxml.ydir_tw_hotlist_data%2Cxml.summary%2Cclustercollision%2Cxml.pi_info%2Cpage_adult_overridable%2Cpage_spam_overridable%2Ccategory_ydir%2Chate_edb&Unique=doc%2Chost+2&QueryEncoding=utf-8&Query=ALLWORDS%28yahoo%29&Database=dewownrm-zh-tw&FirstResult=0&srcpvid=&cacheecho=1&ResultsEncoding=utf-8&QueryLanguage=Chinese-traditional&Region=US&NumResults=10&Client=yahoous2 - 757 - 16217 - - - -
diff --git a/container-search/src/test/java/com/yahoo/search/handler/test/JSONSearchHandlerTestCase.java b/container-search/src/test/java/com/yahoo/search/handler/test/JSONSearchHandlerTestCase.java index d2f6721a0ab..9617e0ceb25 100644 --- a/container-search/src/test/java/com/yahoo/search/handler/test/JSONSearchHandlerTestCase.java +++ b/container-search/src/test/java/com/yahoo/search/handler/test/JSONSearchHandlerTestCase.java @@ -244,22 +244,6 @@ public class JSONSearchHandlerTestCase { assertJsonResult(json, driver); } - @Test - public void testResultLegacyTiledFormat() throws Exception { - JSONObject json = new JSONObject(); - json.put("query", "abc"); - json.put("format", "tiled"); - assertTiledResult(json, driver); - } - - @Test - public void testResultLegacyPageFormat() throws Exception { - JSONObject json = new JSONObject(); - json.put("query", "abc"); - json.put("format", "page"); - assertPageResult(json, driver); - } - private static final String xmlResult = "\n" + "\n" + @@ -284,21 +268,6 @@ public class JSONSearchHandlerTestCase { } - private static final String tiledResult = - "\n" + - "\n" + - "\n" + - " \n" + - " testHit\n" + - " testHit\n" + - " \n" + - "\n" + - "\n"; - - private void assertTiledResult(JSONObject json, RequestHandlerTestDriver driver) { - assertOkResult(driver.sendRequest(uri, com.yahoo.jdisc.http.HttpRequest.Method.POST, json.toString(), JSON_CONTENT_TYPE), tiledResult); - } - private static final String pageResult = "\n" + "\n" + @@ -312,10 +281,6 @@ public class JSONSearchHandlerTestCase { "\n" + "\n"; - private void assertPageResult(JSONObject json, RequestHandlerTestDriver driver) { - assertOkResult(driver.sendRequest(uri, com.yahoo.jdisc.http.HttpRequest.Method.POST, json.toString(), JSON_CONTENT_TYPE), pageResult); - } - private void assertOkResult(RequestHandlerTestDriver.MockResponseHandler response, String expected) { assertEquals(expected, response.readAll()); assertEquals(200, response.getStatus()); @@ -508,7 +473,6 @@ public class JSONSearchHandlerTestCase { assertEquals("Should have same mapping for properties", map, propertyMap); } - @Test public void testContentTypeParsing() throws Exception { JSONObject json = new JSONObject(); diff --git a/container-search/src/test/java/com/yahoo/search/handler/test/SearchHandlerTestCase.java b/container-search/src/test/java/com/yahoo/search/handler/test/SearchHandlerTestCase.java index 1b44fc13b56..20b18ba6723 100644 --- a/container-search/src/test/java/com/yahoo/search/handler/test/SearchHandlerTestCase.java +++ b/container-search/src/test/java/com/yahoo/search/handler/test/SearchHandlerTestCase.java @@ -105,12 +105,12 @@ public class SearchHandlerTestCase { } @Test - public void testFailing() throws Exception { + public void testFailing() { assertTrue(driver.sendRequest("http://localhost?query=test&searchChain=classLoadingError").readAll().contains("NoClassDefFoundError")); } @Test - public synchronized void testPluginError() throws Exception { + public synchronized void testPluginError() { assertTrue(driver.sendRequest("http://localhost?query=test&searchChain=exceptionInPlugin").readAll().contains("NullPointerException")); } @@ -191,7 +191,7 @@ public class SearchHandlerTestCase { } } @Test - public void testInvalidQueryParamWithoutQueryProfile() throws Exception { + public void testInvalidQueryParamWithoutQueryProfile() { testInvalidQueryParam(driver); } private void testInvalidQueryParam(final RequestHandlerTestDriver testDriver) { @@ -213,45 +213,35 @@ public class SearchHandlerTestCase { } @Test - public void testNormalResultImplicitDefaultRendering() throws Exception { + public void testNormalResultImplicitDefaultRendering() { assertJsonResult("http://localhost?query=abc", driver); } @Test - public void testNormalResultExplicitDefaultRendering() throws Exception { + public void testNormalResultExplicitDefaultRendering() { assertJsonResult("http://localhost?query=abc&format=default", driver); } @Test - public void testNormalResultXmlAliasRendering() throws Exception { + public void testNormalResultXmlAliasRendering() { assertXmlResult("http://localhost?query=abc&format=xml", driver); } @Test - public void testNormalResultJsonAliasRendering() throws Exception { + public void testNormalResultJsonAliasRendering() { assertJsonResult("http://localhost?query=abc&format=json", driver); } @Test - public void testNormalResultExplicitDefaultRenderingFullRendererName1() throws Exception { + public void testNormalResultExplicitDefaultRenderingFullRendererName1() { assertXmlResult("http://localhost?query=abc&format=XmlRenderer", driver); } @Test - public void testNormalResultExplicitDefaultRenderingFullRendererName2() throws Exception { + public void testNormalResultExplicitDefaultRenderingFullRendererName2() { assertJsonResult("http://localhost?query=abc&format=JsonRenderer", driver); } - @Test - public void testResultLegacyTiledFormat() throws Exception { - assertTiledResult("http://localhost?query=abc&format=tiled", driver); - } - - @Test - public void testResultLegacyPageFormat() throws Exception { - assertPageResult("http://localhost?query=abc&format=page", driver); - } - private static final String xmlResult = "\n" + "\n" + @@ -260,10 +250,12 @@ public class SearchHandlerTestCase { " testHit\n" + " \n" + "\n"; - private void assertXmlResult(String request, RequestHandlerTestDriver driver) throws Exception { + + private void assertXmlResult(String request, RequestHandlerTestDriver driver) { assertOkResult(driver.sendRequest(request), xmlResult); } - private void assertXmlResult(RequestHandlerTestDriver driver) throws Exception { + + private void assertXmlResult(RequestHandlerTestDriver driver) { assertXmlResult("http://localhost?query=abc", driver); } @@ -272,38 +264,9 @@ public class SearchHandlerTestCase { + "\"children\":[" + "{\"id\":\"testHit\",\"relevance\":1.0,\"fields\":{\"uri\":\"testHit\"}}" + "]}}"; - private void assertJsonResult(String request, RequestHandlerTestDriver driver) throws Exception { - assertOkResult(driver.sendRequest(request), jsonResult); - } - - private static final String tiledResult = - "\n" + - "\n" + - "\n" + - " \n" + - " testHit\n" + - " testHit\n" + - " \n" + - "\n" + - "\n"; - private void assertTiledResult(String request, RequestHandlerTestDriver driver) throws Exception { - assertOkResult(driver.sendRequest(request), tiledResult); - } - private static final String pageResult = - "\n" + - "\n" + - "\n" + - " \n" + - " \n" + - " testHit\n" + - " testHit\n" + - " \n" + - " \n" + - "\n" + - "\n"; - private void assertPageResult(String request, RequestHandlerTestDriver driver) throws Exception { - assertOkResult(driver.sendRequest(request), pageResult); + private void assertJsonResult(String request, RequestHandlerTestDriver driver) { + assertOkResult(driver.sendRequest(request), jsonResult); } private void assertOkResult(RequestHandlerTestDriver.MockResponseHandler response, String expected) { diff --git a/container-search/src/test/java/com/yahoo/search/result/TemplatingTestCase.java b/container-search/src/test/java/com/yahoo/search/result/TemplatingTestCase.java deleted file mode 100644 index 13d0c64a0c2..00000000000 --- a/container-search/src/test/java/com/yahoo/search/result/TemplatingTestCase.java +++ /dev/null @@ -1,174 +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.search.result; - -import static org.junit.Assert.*; - -import java.io.IOException; -import java.io.Writer; -import java.util.Arrays; -import java.util.HashSet; -import java.util.Set; - -import com.yahoo.search.rendering.Renderer; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import com.google.common.base.Splitter; -import com.yahoo.prelude.fastsearch.FastHit; -import com.yahoo.prelude.templates.UserTemplate; -import com.yahoo.prelude.templates.test.BoomTemplate; -import com.yahoo.search.Query; -import com.yahoo.search.Result; - -/** - * Control helper method for result rendering/result templates. - * - * @author Steinar Knutsen - */ -public class TemplatingTestCase { - Result result; - - @Before - public void setUp() throws Exception { - Query q = new Query("/?query=a&presentation.format=nalle&offset=1&hits=5"); - result = new Result(q); - result.setTotalHitCount(1000L); - result.hits().add(new FastHit("http://localhost/1", .95)); - result.hits().add(new FastHit("http://localhost/2", .90)); - result.hits().add(new FastHit("http://localhost/3", .85)); - result.hits().add(new FastHit("http://localhost/4", .80)); - result.hits().add(new FastHit("http://localhost/5", .75)); - } - - @After - public void tearDown() throws Exception { - } - - @Test - public final void testGetFirstHitNo() { - assertEquals(2, result.getTemplating().getFirstHitNo()); - } - - @Test - public final void testGetNextFirstHitNo() { - assertEquals(7, result.getTemplating().getNextFirstHitNo()); - result.getQuery().setHits(6); - assertEquals(0, result.getTemplating().getNextFirstHitNo()); - } - - @Test - public final void testGetNextLastHitNo() { - assertEquals(11, result.getTemplating().getNextLastHitNo()); - result.getQuery().setHits(6); - assertEquals(0, result.getTemplating().getNextLastHitNo()); - } - - @Test - public final void testGetLastHitNo() { - assertEquals(6, result.getTemplating().getLastHitNo()); - } - - @Test - public final void testGetPrevFirstHitNo() { - assertEquals(1, result.getTemplating().getPrevFirstHitNo()); - } - - @Test - public final void testGetPrevLastHitNo() { - assertEquals(1, result.getTemplating().getPrevLastHitNo()); - } - - @Test - public final void testGetNextResultURL() { - String next = result.getTemplating().getNextResultURL(); - Set expectedParameters = new HashSet<>(Arrays.asList(new String[] { - "hits=5", - "query=a", - "presentation.format=nalle", - "offset=6" - })); - Set actualParameters = new HashSet<>(); - Splitter s = Splitter.on("&"); - for (String parameter : s.split(next.substring(next.indexOf('?') + 1))) { - actualParameters.add(parameter); - } - assertEquals(expectedParameters, actualParameters); - } - - @Test - public final void testGetPreviousResultURL() { - String previous = result.getTemplating().getPreviousResultURL(); - Set expectedParameters = new HashSet<>(Arrays.asList(new String[] { - "hits=5", - "query=a", - "presentation.format=nalle", - "offset=0" - })); - Set actualParameters = new HashSet<>(); - Splitter s = Splitter.on("&"); - for (String parameter : s.split(previous.substring(previous.indexOf('?') + 1))) { - actualParameters.add(parameter); - } - assertEquals(expectedParameters, actualParameters); - } - - @Test - public final void testGetCurrentResultURL() { - String previous = result.getTemplating().getCurrentResultURL(); - Set expectedParameters = new HashSet<>(Arrays.asList(new String[] { - "hits=5", - "query=a", - "presentation.format=nalle", - "offset=1" - })); - Set actualParameters = new HashSet<>(); - Splitter s = Splitter.on("&"); - for (String parameter : s.split(previous.substring(previous.indexOf('?') + 1))) { - actualParameters.add(parameter); - } - assertEquals(expectedParameters, actualParameters); - } - - @Test - public final void testGetTemplates() { - @SuppressWarnings({ "unchecked", "deprecation" }) - UserTemplate t = result.getTemplating().getTemplates(); - assertEquals("default", t.getName()); - } - - @SuppressWarnings("deprecation") - @Test - public final void testSetTemplates() { - result.getTemplating().setTemplates(new BoomTemplate("gnuff", "text/plain", "ISO-8859-15")); - @SuppressWarnings("unchecked") - UserTemplate t = result.getTemplating().getTemplates(); - assertEquals("gnuff", t.getName()); - } - - private static class TestRenderer extends Renderer { - - @Override - public void render(Writer writer, Result result) throws IOException { - } - - @Override - public String getEncoding() { - return null; - } - - @Override - public String getMimeType() { - return null; - } - } - - @SuppressWarnings("deprecation") - @Test - public final void testUsesDefaultTemplate() { - assertTrue(result.getTemplating().usesDefaultTemplate()); - result.getTemplating().setRenderer(new TestRenderer()); - assertFalse(result.getTemplating().usesDefaultTemplate()); - } - -} -- cgit v1.2.3