3 * Copyright (C) 2009-2019 SonarSource SA
4 * mailto:info AT sonarsource DOT com
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 3 of the License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 package org.sonar.server.es.newindex;
22 import com.google.common.collect.ImmutableSortedMap;
23 import java.util.Arrays;
24 import java.util.Locale;
25 import java.util.SortedMap;
26 import org.elasticsearch.common.settings.Settings;
27 import org.elasticsearch.common.settings.Settings.Builder;
29 import static org.sonar.server.es.newindex.DefaultIndexSettings.ANALYSIS;
30 import static org.sonar.server.es.newindex.DefaultIndexSettings.ANALYZER;
31 import static org.sonar.server.es.newindex.DefaultIndexSettings.ASCIIFOLDING;
32 import static org.sonar.server.es.newindex.DefaultIndexSettings.CHAR_FILTER;
33 import static org.sonar.server.es.newindex.DefaultIndexSettings.DELIMITER;
34 import static org.sonar.server.es.newindex.DefaultIndexSettings.FIELDDATA_ENABLED;
35 import static org.sonar.server.es.newindex.DefaultIndexSettings.FIELD_FIELDDATA;
36 import static org.sonar.server.es.newindex.DefaultIndexSettings.FIELD_TYPE_TEXT;
37 import static org.sonar.server.es.newindex.DefaultIndexSettings.FILTER;
38 import static org.sonar.server.es.newindex.DefaultIndexSettings.HTML_STRIP;
39 import static org.sonar.server.es.newindex.DefaultIndexSettings.INDEX;
40 import static org.sonar.server.es.newindex.DefaultIndexSettings.INDEX_SEARCHABLE;
41 import static org.sonar.server.es.newindex.DefaultIndexSettings.KEYWORD;
42 import static org.sonar.server.es.newindex.DefaultIndexSettings.LOWERCASE;
43 import static org.sonar.server.es.newindex.DefaultIndexSettings.MAXIMUM_NGRAM_LENGTH;
44 import static org.sonar.server.es.newindex.DefaultIndexSettings.MAX_GRAM;
45 import static org.sonar.server.es.newindex.DefaultIndexSettings.MINIMUM_NGRAM_LENGTH;
46 import static org.sonar.server.es.newindex.DefaultIndexSettings.MIN_GRAM;
47 import static org.sonar.server.es.newindex.DefaultIndexSettings.PATTERN;
48 import static org.sonar.server.es.newindex.DefaultIndexSettings.PORTER_STEM;
49 import static org.sonar.server.es.newindex.DefaultIndexSettings.SEARCH_ANALYZER;
50 import static org.sonar.server.es.newindex.DefaultIndexSettings.STANDARD;
51 import static org.sonar.server.es.newindex.DefaultIndexSettings.STOP;
52 import static org.sonar.server.es.newindex.DefaultIndexSettings.SUB_FIELD_DELIMITER;
53 import static org.sonar.server.es.newindex.DefaultIndexSettings.TOKENIZER;
54 import static org.sonar.server.es.newindex.DefaultIndexSettings.TRIM;
55 import static org.sonar.server.es.newindex.DefaultIndexSettings.TYPE;
56 import static org.sonar.server.es.newindex.DefaultIndexSettings.WHITESPACE;
58 public enum DefaultIndexSettingsElement {
65 protected void setup() {
66 set(TYPE, "word_delimiter");
67 set("generate_word_parts", true);
68 set("catenate_words", true);
69 set("catenate_numbers", true);
70 set("catenate_all", true);
71 set("split_on_case_change", true);
72 set("preserve_original", true);
73 set("split_on_numerics", true);
74 set("stem_english_possessive", true);
77 NGRAM_FILTER(FILTER) {
80 protected void setup() {
82 set(MIN_GRAM, MINIMUM_NGRAM_LENGTH);
83 set(MAX_GRAM, MAXIMUM_NGRAM_LENGTH);
84 setList("token_chars", "letter", "digit", "punctuation", "symbol");
90 GRAM_TOKENIZER(TOKENIZER) {
93 protected void setup() {
95 set(MIN_GRAM, MINIMUM_NGRAM_LENGTH);
96 set(MAX_GRAM, MAXIMUM_NGRAM_LENGTH);
97 setList("token_chars", "letter", "digit", "punctuation", "symbol");
100 PREFIX_TOKENIZER(TOKENIZER) {
103 protected void setup() {
104 set(TYPE, "edgeNGram");
105 set(MIN_GRAM, MINIMUM_NGRAM_LENGTH);
106 set(MAX_GRAM, MAXIMUM_NGRAM_LENGTH);
109 UUID_MODULE_TOKENIZER(TOKENIZER) {
112 protected void setup() {
120 SORTABLE_ANALYZER(ANALYZER) {
123 protected void setup() {
124 set(TOKENIZER, KEYWORD);
125 setList(FILTER, TRIM, LOWERCASE);
129 public SortedMap<String, String> fieldMapping() {
130 return ImmutableSortedMap.of(
131 TYPE, FIELD_TYPE_TEXT,
132 INDEX, INDEX_SEARCHABLE,
134 FIELD_FIELDDATA, FIELDDATA_ENABLED);
137 INDEX_GRAMS_ANALYZER(ANALYZER) {
140 protected void setup() {
141 set(TOKENIZER, GRAM_TOKENIZER);
142 setList(FILTER, TRIM, LOWERCASE);
145 SEARCH_GRAMS_ANALYZER(ANALYZER) {
148 protected void setup() {
149 set(TOKENIZER, WHITESPACE);
150 setList(FILTER, TRIM, LOWERCASE);
154 public SortedMap<String, String> fieldMapping() {
155 return ImmutableSortedMap.of(
156 TYPE, FIELD_TYPE_TEXT,
157 INDEX, INDEX_SEARCHABLE,
158 ANALYZER, INDEX_GRAMS_ANALYZER.getName(),
159 SEARCH_ANALYZER, getName());
162 INDEX_PREFIX_ANALYZER(ANALYZER) {
165 protected void setup() {
166 set(TOKENIZER, PREFIX_TOKENIZER);
167 setList(FILTER, TRIM);
170 SEARCH_PREFIX_ANALYZER(ANALYZER) {
173 protected void setup() {
174 set(TOKENIZER, WHITESPACE);
175 setList(FILTER, TRIM);
179 public SortedMap<String, String> fieldMapping() {
180 return ImmutableSortedMap.of(
181 TYPE, FIELD_TYPE_TEXT,
182 INDEX, INDEX_SEARCHABLE,
183 ANALYZER, INDEX_PREFIX_ANALYZER.getName(),
184 SEARCH_ANALYZER, getName());
187 INDEX_PREFIX_CASE_INSENSITIVE_ANALYZER(ANALYZER) {
190 protected void setup() {
191 set(TOKENIZER, PREFIX_TOKENIZER);
192 setList(FILTER, TRIM, LOWERCASE);
195 SEARCH_PREFIX_CASE_INSENSITIVE_ANALYZER(ANALYZER) {
198 protected void setup() {
199 set(TOKENIZER, WHITESPACE);
200 setList(FILTER, TRIM, LOWERCASE);
204 public SortedMap<String, String> fieldMapping() {
205 return ImmutableSortedMap.of(
206 TYPE, FIELD_TYPE_TEXT,
207 INDEX, INDEX_SEARCHABLE,
208 ANALYZER, INDEX_PREFIX_CASE_INSENSITIVE_ANALYZER.getName(),
209 SEARCH_ANALYZER, getName());
212 USER_INDEX_GRAMS_ANALYZER(ANALYZER) {
215 protected void setup() {
216 set(TOKENIZER, WHITESPACE);
217 setList(FILTER, TRIM, LOWERCASE, NGRAM_FILTER.getName());
220 USER_SEARCH_GRAMS_ANALYZER(ANALYZER) {
223 protected void setup() {
224 set(TOKENIZER, WHITESPACE);
225 setList(FILTER, TRIM, LOWERCASE);
229 public SortedMap<String, String> fieldMapping() {
230 return ImmutableSortedMap.of(
231 TYPE, FIELD_TYPE_TEXT,
232 INDEX, INDEX_SEARCHABLE,
233 ANALYZER, USER_INDEX_GRAMS_ANALYZER.getName(),
234 SEARCH_ANALYZER, getName());
237 INDEX_WORDS_ANALYZER(ANALYZER) {
240 protected void setup() {
241 set(TOKENIZER, STANDARD);
242 setList(FILTER, STANDARD, "word_filter", LOWERCASE, STOP, ASCIIFOLDING, PORTER_STEM);
245 SEARCH_WORDS_ANALYZER(ANALYZER) {
248 protected void setup() {
249 set(TOKENIZER, STANDARD);
250 setList(FILTER, STANDARD, LOWERCASE, STOP, ASCIIFOLDING, PORTER_STEM);
254 public SortedMap<String, String> fieldMapping() {
255 return ImmutableSortedMap.of(
256 TYPE, FIELD_TYPE_TEXT,
257 INDEX, INDEX_SEARCHABLE,
258 ANALYZER, INDEX_WORDS_ANALYZER.getName(),
259 SEARCH_ANALYZER, getName());
262 ENGLISH_HTML_ANALYZER(ANALYZER) {
265 protected void setup() {
266 set(TOKENIZER, STANDARD);
267 setList(FILTER, STANDARD, LOWERCASE, STOP, ASCIIFOLDING, PORTER_STEM);
268 setList(CHAR_FILTER, HTML_STRIP);
272 public SortedMap<String, String> fieldMapping() {
273 return ImmutableSortedMap.of(
274 TYPE, FIELD_TYPE_TEXT,
275 INDEX, INDEX_SEARCHABLE,
276 ANALYZER, getName());
279 PATH_ANALYZER(ANALYZER) {
282 protected void setup() {
283 set(TOKENIZER, "path_hierarchy");
286 UUID_MODULE_ANALYZER(ANALYZER) {
289 protected void setup() {
290 set(TOKENIZER, UUID_MODULE_TOKENIZER);
291 setList(FILTER, TRIM);
297 private final String type;
298 private final String name;
300 private Builder builder = Settings.builder();
302 DefaultIndexSettingsElement(String type) {
304 this.name = name().toLowerCase(Locale.ENGLISH);
308 protected void set(String settingSuffix, int value) {
309 put(localName(settingSuffix), Integer.toString(value));
312 protected void set(String settingSuffix, boolean value) {
313 put(localName(settingSuffix), Boolean.toString(value));
316 protected void set(String settingSuffix, DefaultIndexSettingsElement otherElement) {
317 put(localName(settingSuffix), otherElement.name);
320 protected void set(String settingSuffix, String value) {
321 put(localName(settingSuffix), value);
324 protected void setList(String settingSuffix, String... values) {
325 putList(localName(settingSuffix), values);
328 protected void setList(String settingSuffix, DefaultIndexSettingsElement... values) {
329 putList(localName(settingSuffix), Arrays.stream(values).map(DefaultIndexSettingsElement::getName).toArray(String[]::new));
332 private void put(String setting, String value) {
333 builder = builder.put(setting, value);
336 private void putList(String setting, String... values) {
337 builder = builder.putList(setting, values);
340 private String localName(String settingSuffix) {
341 return ANALYSIS + DELIMITER + type + DELIMITER + name + DELIMITER + settingSuffix;
344 public Settings settings() {
345 return builder.build();
348 protected abstract void setup();
350 public SortedMap<String, String> fieldMapping() {
351 throw new UnsupportedOperationException("The elasticsearch configuration element '" + name + "' cannot be used as field mapping.");
354 public String subField(String fieldName) {
355 return fieldName + SUB_FIELD_DELIMITER + getSubFieldSuffix();
358 public String getSubFieldSuffix() {
362 public String getName() {