/*
* Hibernate Search, full-text search for your domain model
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.search.elasticsearch.analyzer.impl;
import java.util.Map;
import org.hibernate.search.annotations.AnalyzerDef;
import org.hibernate.search.annotations.CharFilterDef;
import org.hibernate.search.annotations.TokenFilterDef;
import org.hibernate.search.annotations.TokenizerDef;
import org.hibernate.search.elasticsearch.settings.impl.model.AnalysisDefinition;
import org.hibernate.search.elasticsearch.settings.impl.model.AnalyzerDefinition;
import org.hibernate.search.elasticsearch.settings.impl.model.CharFilterDefinition;
import org.hibernate.search.elasticsearch.settings.impl.model.TokenFilterDefinition;
import org.hibernate.search.elasticsearch.settings.impl.model.TokenizerDefinition;
import org.hibernate.search.elasticsearch.settings.impl.translation.ElasticsearchAnalyzerDefinitionTranslator;
/**
* An {@link ElasticsearchAnalysisDefinitionRegistry} populator that translates {@literal @AnalyzerDef} annotations.
* <p>
* The responsibilities of this class are:
* <ul>
* <li>to break {@literal @AnalyzerDef}s into their components ({@literal @TokenizerDef}, etc.)
* <li>to determine the correct name for each components (generating names automatically if needed)
* <li>to store the translated definitions in the registry
* <li>to detect illegal definitions that override pre-existing definitions
* </ul>
* <p>
* The actual translation job (e.g. {@literal @AnalyzerDef} to {@link AnalyzerDefinition})
* is delegated to an {@link ElasticsearchAnalyzerDefinitionTranslator}.
*
* @author Yoann Rodiere
*/
public class TranslatingElasticsearchAnalyzerDefinitionRegistryPopulator {
private final ElasticsearchAnalysisDefinitionRegistry registry;
private final ElasticsearchAnalyzerDefinitionTranslator translator;
public TranslatingElasticsearchAnalyzerDefinitionRegistryPopulator(ElasticsearchAnalysisDefinitionRegistry registry,
ElasticsearchAnalyzerDefinitionTranslator translator) {
this.registry = registry;
this.translator = translator;
}
public void registerAnalyzerDef(AnalyzerDef hibernateSearchDefinition) {
AnalyzerDefinition elasticsearchDefinition = new AnalyzerDefinition();
String localName = hibernateSearchDefinition.name();
String remoteName = localName; // We use the same definition name in Elasticsearch
TokenizerDef hibernateSearchTokenizerDef = hibernateSearchDefinition.tokenizer();
String tokenizerName = registerTokenizerDef( localName, hibernateSearchTokenizerDef );
elasticsearchDefinition.setTokenizer( tokenizerName );
for ( CharFilterDef hibernateSearchCharFilterDef : hibernateSearchDefinition.charFilters() ) {
String charFilterName = registerCharFilterDef( localName, hibernateSearchCharFilterDef );
elasticsearchDefinition.addCharFilter( charFilterName );
}
for ( TokenFilterDef hibernateSearchTokenFilterDef : hibernateSearchDefinition.filters() ) {
String tokenFilterName = registerTokenFilterDef( localName, hibernateSearchTokenFilterDef );
elasticsearchDefinition.addTokenFilter( tokenFilterName );
}
registry.register( remoteName, elasticsearchDefinition );
}
private String registerTokenizerDef(String analyzerDefinitionName, TokenizerDef hibernateSearchDef) {
String remoteName = hibernateSearchDef.name();
TokenizerDefinition elasticsearchDefinition = translator.translate( hibernateSearchDef );
if ( remoteName.isEmpty() && !hasParameters( elasticsearchDefinition ) ) {
// No parameters, and no specific name was provided => Use the builtin, default definition
remoteName = elasticsearchDefinition.getType();
}
else {
if ( remoteName.isEmpty() ) {
remoteName = analyzerDefinitionName + "_" + hibernateSearchDef.factory().getSimpleName();
}
registry.register( remoteName, elasticsearchDefinition );
}
return remoteName;
}
private String registerCharFilterDef(String analyzerDefinitionName, CharFilterDef hibernateSearchDef) {
String remoteName = hibernateSearchDef.name();
CharFilterDefinition elasticsearchDefinition = translator.translate( hibernateSearchDef );
if ( remoteName.isEmpty() && !hasParameters( elasticsearchDefinition ) ) {
// No parameters, and no specific name was provided => Use the builtin, default definition
remoteName = elasticsearchDefinition.getType();
}
else {
if ( remoteName.isEmpty() ) {
remoteName = analyzerDefinitionName + "_" + hibernateSearchDef.factory().getSimpleName();
}
registry.register( remoteName, elasticsearchDefinition );
}
return remoteName;
}
private String registerTokenFilterDef(String analyzerDefinitionName, TokenFilterDef hibernateSearchDef) {
String remoteName = hibernateSearchDef.name();
TokenFilterDefinition elasticsearchDefinition = translator.translate( hibernateSearchDef );
if ( remoteName.isEmpty() && !hasParameters( elasticsearchDefinition ) ) {
// No parameters, and no specific name was provided => Use the builtin, default definition
remoteName = elasticsearchDefinition.getType();
}
else {
if ( remoteName.isEmpty() ) {
remoteName = analyzerDefinitionName + "_" + hibernateSearchDef.factory().getSimpleName();
}
registry.register( remoteName, elasticsearchDefinition );
}
return remoteName;
}
private boolean hasParameters(AnalysisDefinition definition) {
Map<?, ?> parameters = definition.getParameters();
return parameters != null && !parameters.isEmpty();
}
}