/*
* 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.engine.impl;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.hibernate.search.analyzer.spi.AnalyzerReference;
import org.hibernate.search.analyzer.spi.AnalyzerStrategy;
import org.hibernate.search.analyzer.spi.ScopedAnalyzerReference;
import org.hibernate.search.analyzer.spi.ScopedAnalyzerReference.Builder;
import org.hibernate.search.annotations.AnalyzerDef;
import org.hibernate.search.util.impl.Closeables;
/**
* This class gives access to the set of analyzer references created for a given index manager type,
* creating new ones as necessary using the {@link AnalyzerStrategy} of that index manager type.
*
* @author Yoann Rodiere
*/
public class MutableAnalyzerRegistry implements AnalyzerRegistry {
private final AnalyzerStrategy strategy;
private final AnalyzerReference defaultReference;
private final AnalyzerReference passThroughReference;
private final Map<String, AnalyzerReference> referencesByName = new LinkedHashMap<>();
private final Map<Class<?>, AnalyzerReference> referencesByLuceneClass = new LinkedHashMap<>();
private final Collection<AnalyzerReference> scopedReferences = new ArrayList<>();
MutableAnalyzerRegistry(AnalyzerStrategy strategy) {
this( strategy, null );
}
MutableAnalyzerRegistry(AnalyzerStrategy strategy, AnalyzerRegistry registryState) {
this.strategy = strategy;
if ( registryState != null ) {
this.defaultReference = registryState.getDefaultAnalyzerReference();
this.passThroughReference = registryState.getPassThroughAnalyzerReference();
this.referencesByName.putAll( registryState.getNamedAnalyzerReferences() );
this.referencesByLuceneClass.putAll( registryState.getLuceneClassAnalyzerReferences() );
}
else {
this.defaultReference = strategy.createDefaultAnalyzerReference();
this.passThroughReference = strategy.createPassThroughAnalyzerReference();
}
}
@Override
public AnalyzerReference getDefaultAnalyzerReference() {
return defaultReference;
}
@Override
public AnalyzerReference getPassThroughAnalyzerReference() {
return passThroughReference;
}
@Override
public Map<String, AnalyzerReference> getNamedAnalyzerReferences() {
return Collections.unmodifiableMap( referencesByName );
}
@Override
public Map<Class<?>, AnalyzerReference> getLuceneClassAnalyzerReferences() {
return Collections.unmodifiableMap( referencesByLuceneClass );
}
@Override
public Collection<AnalyzerReference> getScopedAnalyzerReferences() {
return Collections.unmodifiableCollection( scopedReferences );
}
@Override
public AnalyzerReference getAnalyzerReference(String name) {
return referencesByName.get( name );
}
public AnalyzerReference getOrCreateAnalyzerReference(String name) {
AnalyzerReference reference = referencesByName.get( name );
if ( reference == null ) {
reference = strategy.createNamedAnalyzerReference( name );
referencesByName.put( name, reference );
}
return reference;
}
@Override
public AnalyzerReference getAnalyzerReference(Class<?> analyzerClazz) {
return referencesByLuceneClass.get( analyzerClazz );
}
public AnalyzerReference getOrCreateAnalyzerReference(Class<?> analyzerClazz) {
AnalyzerReference reference = referencesByLuceneClass.get( analyzerClazz );
if ( reference == null ) {
reference = strategy.createLuceneClassAnalyzerReference( analyzerClazz );
referencesByLuceneClass.put( analyzerClazz, reference );
}
return reference;
}
@Override
public void close() {
Closeables.closeQuietly( getAllReferences() );
}
public void initialize(Map<String, AnalyzerDef> mappingAnalyzerDefinitions) {
List<AnalyzerReference> references = getAllReferences();
Map<String, AnalyzerReference> additionalReferences =
strategy.initializeAnalyzerReferences( references, mappingAnalyzerDefinitions );
referencesByName.putAll( additionalReferences );
}
public ScopedAnalyzerReference.Builder buildScopedAnalyzerReference() {
return new ScopedAnalyzerReferenceBuilderRegisteringWrapper(
strategy.buildScopedAnalyzerReference( getDefaultAnalyzerReference() )
);
}
private List<AnalyzerReference> getAllReferences() {
List<AnalyzerReference> references = new ArrayList<>();
references.add( defaultReference );
references.add( passThroughReference );
references.addAll( referencesByName.values() );
references.addAll( referencesByLuceneClass.values() );
references.addAll( scopedReferences );
return references;
}
/**
* A builder that will delegate to another builder for all operations, but will also add any
* built reference to the registry.
*
* @author Yoann Rodiere
*/
private class ScopedAnalyzerReferenceBuilderRegisteringWrapper implements ScopedAnalyzerReference.Builder {
private final ScopedAnalyzerReference.Builder delegate;
public ScopedAnalyzerReferenceBuilderRegisteringWrapper(Builder delegate) {
super();
this.delegate = delegate;
}
@Override
public AnalyzerReference getGlobalAnalyzerReference() {
return delegate.getGlobalAnalyzerReference();
}
@Override
public void setGlobalAnalyzerReference(AnalyzerReference globalAnalyzerReference) {
delegate.setGlobalAnalyzerReference( globalAnalyzerReference );
}
@Override
public void addAnalyzerReference(String scope, AnalyzerReference analyzerReference) {
delegate.addAnalyzerReference( scope, analyzerReference );
}
@Override
public ScopedAnalyzerReference build() {
ScopedAnalyzerReference reference = delegate.build();
// Register the newly built reference
scopedReferences.add( reference );
return reference;
}
}
}