Commit b75b604799280eb3de7368e12a8602970b558b24

Authored by Gethin James
Exists in master

Merge branch 'feature/SEARCH-106-highlighting' into 'master'

Feature/search 106 highlighting

Adds Search highlighting to the SearchParameters Java Object and ResultSetSPI response. Also depends on Jackson annotations for the object constructor.

//cc @jvonka

See merge request !1
... ... @@ -172,6 +172,12 @@
172 172 </dependency>
173 173  
174 174 <dependency>
  175 + <groupId>org.codehaus.jackson</groupId>
  176 + <artifactId>jackson-core-asl</artifactId>
  177 + <version>1.9.13</version>
  178 + </dependency>
  179 +
  180 + <dependency>
175 181 <groupId>org.antlr</groupId>
176 182 <artifactId>antlr</artifactId>
177 183 <version>3.5.2</version>
... ...
src/main/java/org/alfresco/service/cmr/search/FieldHighlightParameters.java
... ... @@ -0,0 +1,97 @@
  1 +/*
  2 + * #%L
  3 + * Alfresco Data model classes
  4 + * %%
  5 + * Copyright (C) 2005 - 2016 Alfresco Software Limited
  6 + * %%
  7 + * This file is part of the Alfresco software.
  8 + * If the software was purchased under a paid Alfresco license, the terms of
  9 + * the paid license agreement will prevail. Otherwise, the software is
  10 + * provided under the following open source license terms:
  11 + *
  12 + * Alfresco is free software: you can redistribute it and/or modify
  13 + * it under the terms of the GNU Lesser General Public License as published by
  14 + * the Free Software Foundation, either version 3 of the License, or
  15 + * (at your option) any later version.
  16 + *
  17 + * Alfresco is distributed in the hope that it will be useful,
  18 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  20 + * GNU Lesser General Public License for more details.
  21 + *
  22 + * You should have received a copy of the GNU Lesser General Public License
  23 + * along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
  24 + * #L%
  25 + */
  26 +package org.alfresco.service.cmr.search;
  27 +
  28 +import org.alfresco.api.AlfrescoPublicApi;
  29 +import org.codehaus.jackson.annotate.JsonCreator;
  30 +import org.codehaus.jackson.annotate.JsonProperty;
  31 +
  32 +/**
  33 + * Parameters used for search hightlighting that are Field Specific
  34 + */
  35 +
  36 +@AlfrescoPublicApi
  37 +public class FieldHighlightParameters extends HighlightParameters
  38 +{
  39 + private final String field;
  40 +
  41 + @JsonCreator
  42 + public FieldHighlightParameters(
  43 + @JsonProperty("field") String field,
  44 + @JsonProperty("snippetCount") Integer snippetCount,
  45 + @JsonProperty("fragmentSize") Integer fragmentSize,
  46 + @JsonProperty("mergeContiguous") Boolean mergeContiguous,
  47 + @JsonProperty("prefix") String prefix,
  48 + @JsonProperty("postfix") String postfix)
  49 + {
  50 + super(snippetCount, fragmentSize, mergeContiguous, prefix, postfix);
  51 + this.field = field;
  52 + }
  53 +
  54 + @Override
  55 + public String toString()
  56 + {
  57 + return "FieldHighlightParameters{" +
  58 + "snippetCount=" + snippetCount +
  59 + ", fragmentSize=" + fragmentSize +
  60 + ", mergeContiguous=" + mergeContiguous +
  61 + ", prefix='" + prefix + '\'' +
  62 + ", postfix='" + postfix + '\'' +
  63 + ", field='" + field + '\'' +
  64 + '}';
  65 + }
  66 +
  67 + public String getField()
  68 + {
  69 + return field;
  70 + }
  71 +
  72 + @Override
  73 + public boolean equals(Object o)
  74 + {
  75 + if (this == o)
  76 + return true;
  77 + if (o == null || getClass() != o.getClass())
  78 + return false;
  79 + if (!super.equals(o))
  80 + return false;
  81 +
  82 + FieldHighlightParameters that = (FieldHighlightParameters) o;
  83 +
  84 + if (field != null ? !field.equals(that.field) : that.field != null)
  85 + return false;
  86 +
  87 + return true;
  88 + }
  89 +
  90 + @Override
  91 + public int hashCode()
  92 + {
  93 + int result = super.hashCode();
  94 + result = 31 * result + (field != null ? field.hashCode() : 0);
  95 + return result;
  96 + }
  97 +}
... ...
src/main/java/org/alfresco/service/cmr/search/GeneralHighlightParameters.java
... ... @@ -0,0 +1,127 @@
  1 +/*
  2 + * #%L
  3 + * Alfresco Data model classes
  4 + * %%
  5 + * Copyright (C) 2005 - 2016 Alfresco Software Limited
  6 + * %%
  7 + * This file is part of the Alfresco software.
  8 + * If the software was purchased under a paid Alfresco license, the terms of
  9 + * the paid license agreement will prevail. Otherwise, the software is
  10 + * provided under the following open source license terms:
  11 + *
  12 + * Alfresco is free software: you can redistribute it and/or modify
  13 + * it under the terms of the GNU Lesser General Public License as published by
  14 + * the Free Software Foundation, either version 3 of the License, or
  15 + * (at your option) any later version.
  16 + *
  17 + * Alfresco is distributed in the hope that it will be useful,
  18 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  20 + * GNU Lesser General Public License for more details.
  21 + *
  22 + * You should have received a copy of the GNU Lesser General Public License
  23 + * along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
  24 + * #L%
  25 + */
  26 +package org.alfresco.service.cmr.search;
  27 +
  28 +import org.alfresco.api.AlfrescoPublicApi;
  29 +import org.codehaus.jackson.annotate.JsonCreator;
  30 +import org.codehaus.jackson.annotate.JsonProperty;
  31 +
  32 +import java.util.List;
  33 +
  34 +/**
  35 + * Parameters used for search hightlighting that apply to all fields
  36 + */
  37 +
  38 +@AlfrescoPublicApi
  39 +public class GeneralHighlightParameters extends HighlightParameters
  40 +{
  41 + private final Integer maxAnalyzedChars;
  42 + private final Boolean usePhraseHighlighter;
  43 +
  44 + private final List<FieldHighlightParameters> fields;
  45 +
  46 + @JsonCreator
  47 + public GeneralHighlightParameters(
  48 + @JsonProperty("snippetCount") Integer snippetCount,
  49 + @JsonProperty("fragmentSize") Integer fragmentSize,
  50 + @JsonProperty("mergeContiguous") Boolean mergeContiguous,
  51 + @JsonProperty("prefix") String prefix,
  52 + @JsonProperty("postfix") String postfix,
  53 + @JsonProperty("maxAnalyzedChars") Integer maxAnalyzedChars,
  54 + @JsonProperty("usePhraseHighlighter") Boolean usePhraseHighlighter,
  55 + @JsonProperty("fields") List<FieldHighlightParameters> fields)
  56 + {
  57 + super(snippetCount, fragmentSize, mergeContiguous, prefix, postfix);
  58 + this.maxAnalyzedChars = maxAnalyzedChars;
  59 + this.usePhraseHighlighter = usePhraseHighlighter;
  60 + this.fields = fields;
  61 + }
  62 +
  63 + @Override
  64 + public String toString()
  65 + {
  66 + return "GeneralHighlightParameters{" +
  67 + "snippetCount=" + snippetCount +
  68 + ", fragmentSize=" + fragmentSize +
  69 + ", mergeContiguous=" + mergeContiguous +
  70 + ", prefix='" + prefix + '\'' +
  71 + ", postfix='" + postfix + '\'' +
  72 + ", maxAnalyzedChars=" + maxAnalyzedChars +
  73 + ", usePhraseHighlighter=" + usePhraseHighlighter +
  74 + ", fields=" + fields +
  75 + '}';
  76 + }
  77 +
  78 + @Override
  79 + public boolean equals(Object o)
  80 + {
  81 + if (this == o)
  82 + return true;
  83 + if (o == null || getClass() != o.getClass())
  84 + return false;
  85 + if (!super.equals(o))
  86 + return false;
  87 +
  88 + GeneralHighlightParameters that = (GeneralHighlightParameters) o;
  89 +
  90 + if (getMaxAnalyzedChars() != null ? !getMaxAnalyzedChars().equals(that.getMaxAnalyzedChars()) : that.getMaxAnalyzedChars() != null)
  91 + return false;
  92 + if (getUsePhraseHighlighter() != null ?
  93 + !getUsePhraseHighlighter().equals(that.getUsePhraseHighlighter()) :
  94 + that.getUsePhraseHighlighter() != null)
  95 + return false;
  96 + if (getFields() != null ? !getFields().equals(that.getFields()) : that.getFields() != null)
  97 + return false;
  98 +
  99 + return true;
  100 + }
  101 +
  102 + @Override
  103 + public int hashCode()
  104 + {
  105 + int result = super.hashCode();
  106 + result = 31 * result + (getMaxAnalyzedChars() != null ? getMaxAnalyzedChars().hashCode() : 0);
  107 + result = 31 * result + (getUsePhraseHighlighter() != null ? getUsePhraseHighlighter().hashCode() : 0);
  108 + result = 31 * result + (getFields() != null ? getFields().hashCode() : 0);
  109 + return result;
  110 + }
  111 +
  112 + public Integer getMaxAnalyzedChars()
  113 + {
  114 + return maxAnalyzedChars;
  115 + }
  116 +
  117 + public Boolean getUsePhraseHighlighter()
  118 + {
  119 + return usePhraseHighlighter;
  120 + }
  121 +
  122 + public List<FieldHighlightParameters> getFields()
  123 + {
  124 + return fields;
  125 + }
  126 +
  127 +}
... ...
src/main/java/org/alfresco/service/cmr/search/HighlightParameters.java
... ... @@ -0,0 +1,128 @@
  1 +/*
  2 + * #%L
  3 + * Alfresco Data model classes
  4 + * %%
  5 + * Copyright (C) 2005 - 2016 Alfresco Software Limited
  6 + * %%
  7 + * This file is part of the Alfresco software.
  8 + * If the software was purchased under a paid Alfresco license, the terms of
  9 + * the paid license agreement will prevail. Otherwise, the software is
  10 + * provided under the following open source license terms:
  11 + *
  12 + * Alfresco is free software: you can redistribute it and/or modify
  13 + * it under the terms of the GNU Lesser General Public License as published by
  14 + * the Free Software Foundation, either version 3 of the License, or
  15 + * (at your option) any later version.
  16 + *
  17 + * Alfresco is distributed in the hope that it will be useful,
  18 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  20 + * GNU Lesser General Public License for more details.
  21 + *
  22 + * You should have received a copy of the GNU Lesser General Public License
  23 + * along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
  24 + * #L%
  25 + */
  26 +package org.alfresco.service.cmr.search;
  27 +
  28 +import org.alfresco.api.AlfrescoPublicApi;
  29 +import org.codehaus.jackson.annotate.JsonCreator;
  30 +import org.codehaus.jackson.annotate.JsonProperty;
  31 +
  32 +/**
  33 + * Parameters used for search hightlighting.
  34 + */
  35 +
  36 +@AlfrescoPublicApi
  37 +public abstract class HighlightParameters
  38 +{
  39 + final Integer snippetCount;
  40 + final Integer fragmentSize;
  41 +
  42 + final Boolean mergeContiguous;
  43 +
  44 + final String prefix;
  45 + final String postfix;
  46 +
  47 + public HighlightParameters(Integer snippetCount, Integer fragmentSize,
  48 + Boolean mergeContiguous, String prefix, String postfix)
  49 + {
  50 + this.snippetCount = snippetCount;
  51 + this.fragmentSize = fragmentSize;
  52 + this.mergeContiguous = mergeContiguous;
  53 + this.prefix = prefix;
  54 + this.postfix = postfix;
  55 + }
  56 +
  57 + @Override
  58 + public boolean equals(Object o)
  59 + {
  60 + if (this == o)
  61 + return true;
  62 + if (o == null || getClass() != o.getClass())
  63 + return false;
  64 +
  65 + HighlightParameters that = (HighlightParameters) o;
  66 +
  67 + if (snippetCount != null ? !snippetCount.equals(that.snippetCount) : that.snippetCount != null)
  68 + return false;
  69 + if (fragmentSize != null ? !fragmentSize.equals(that.fragmentSize) : that.fragmentSize != null)
  70 + return false;
  71 + if (mergeContiguous != null ? !mergeContiguous.equals(that.mergeContiguous) : that.mergeContiguous != null)
  72 + return false;
  73 + if (prefix != null ? !prefix.equals(that.prefix) : that.prefix != null)
  74 + return false;
  75 + if (postfix != null ? !postfix.equals(that.postfix) : that.postfix != null)
  76 + return false;
  77 +
  78 + return true;
  79 + }
  80 +
  81 + @Override
  82 + public int hashCode()
  83 + {
  84 + int result = snippetCount != null ? snippetCount.hashCode() : 0;
  85 + result = 31 * result + (fragmentSize != null ? fragmentSize.hashCode() : 0);
  86 + result = 31 * result + (mergeContiguous != null ? mergeContiguous.hashCode() : 0);
  87 + result = 31 * result + (prefix != null ? prefix.hashCode() : 0);
  88 + result = 31 * result + (postfix != null ? postfix.hashCode() : 0);
  89 + return result;
  90 + }
  91 +
  92 + @Override
  93 + public String toString()
  94 + {
  95 + return "HighlightParameters{" +
  96 + "snippetCount=" + snippetCount +
  97 + ", fragmentSize=" + fragmentSize +
  98 + ", mergeContiguous=" + mergeContiguous +
  99 + ", prefix='" + prefix + '\'' +
  100 + ", postfix='" + postfix + '\'' +
  101 + '}';
  102 + }
  103 +
  104 + public Integer getSnippetCount()
  105 + {
  106 + return snippetCount;
  107 + }
  108 +
  109 + public Integer getFragmentSize()
  110 + {
  111 + return fragmentSize;
  112 + }
  113 +
  114 + public Boolean getMergeContiguous()
  115 + {
  116 + return mergeContiguous;
  117 + }
  118 +
  119 + public String getPrefix()
  120 + {
  121 + return prefix;
  122 + }
  123 +
  124 + public String getPostfix()
  125 + {
  126 + return postfix;
  127 + }
  128 +}
... ...
src/main/java/org/alfresco/service/cmr/search/ResultSetSPI.java
... ... @@ -189,6 +189,12 @@ public interface ResultSetSPI&lt;ROW extends ResultSetRow, MD extends ResultSetMeta
189 189 public Map<String, Integer> getFacetQueries();
190 190  
191 191 /**
  192 + * Gets the highlighting results. Returns a Map keyed by noderef.
  193 + * Each value is a pair of "fieldname" and a String array of highlight snippets
  194 + * @return the Map
  195 + */
  196 + public Map<NodeRef, List<Pair<String, List<String>>>> getHighlighting();
  197 + /**
192 198 * Gets the spell check result
193 199 *
194 200 * @return SpellCheckResult
... ...
src/main/java/org/alfresco/service/cmr/search/SearchParameters.java
... ... @@ -187,6 +187,8 @@ public class SearchParameters implements BasicSearchParameters
187 187  
188 188 private boolean spellCheck;
189 189  
  190 + private GeneralHighlightParameters hightlight;
  191 +
190 192 /**
191 193 * Default constructor
192 194 */
... ... @@ -231,6 +233,7 @@ public class SearchParameters implements BasicSearchParameters
231 233 sp.filterQueries.addAll(this.filterQueries);
232 234 sp.searchTerm = this.searchTerm;
233 235 sp.spellCheck = this.spellCheck;
  236 + sp.hightlight = this.hightlight;
234 237 return sp;
235 238 }
236 239  
... ... @@ -277,6 +280,11 @@ public class SearchParameters implements BasicSearchParameters
277 280 return query;
278 281 }
279 282  
  283 + public void setHightlight(GeneralHighlightParameters hightlight)
  284 + {
  285 + this.hightlight = hightlight;
  286 + }
  287 +
280 288 /**
281 289 * Set the query language.
282 290 *
... ... @@ -371,6 +379,24 @@ public class SearchParameters implements BasicSearchParameters
371 379 }
372 380  
373 381 /**
  382 + * Adds parameters used for search highlighing
  383 + * @param hightlight - the highlighting parameters
  384 + */
  385 + public void addHightlight(GeneralHighlightParameters hightlight)
  386 + {
  387 + this.hightlight = hightlight;
  388 + }
  389 +
  390 + /**
  391 + * Gets the parameters used for search highlighing
  392 + * @return GeneralHighlightParameters - the highlighting parameters
  393 + */
  394 + public GeneralHighlightParameters getHightlight()
  395 + {
  396 + return hightlight;
  397 + }
  398 +
  399 + /**
374 400 * Is data in the current transaction excluded from the search.
375 401 *
376 402 * @return - true if data in the current transaction is ignored
... ... @@ -1231,6 +1257,7 @@ public class SearchParameters implements BasicSearchParameters
1231 1257 .append(this.excludeTenantFilter).append(", isBulkFetchEnabled=").append(this.isBulkFetchEnabled)
1232 1258 .append(", queryConsistency=").append(this.queryConsistency).append(", sinceTxId=")
1233 1259 .append(this.sinceTxId).append(", searchTerm=").append(this.searchTerm)
  1260 + .append(", highlight=").append(this.hightlight)
1234 1261 .append(", spellCheck=").append(this.spellCheck).append("]");
1235 1262 return builder.toString();
1236 1263 }
... ...