Skip to content

Commit

Permalink
HSEARCH-2219 Move scoped analyzers to SPI
Browse files Browse the repository at this point in the history
This is required in order to enable indexing services to define their
own analyzer type, with custom data.
  • Loading branch information
yrodiere authored and Sanne committed Dec 19, 2016
1 parent 13656d1 commit 16f7a5d
Show file tree
Hide file tree
Showing 27 changed files with 286 additions and 231 deletions.
Expand Up @@ -7,12 +7,14 @@
package org.hibernate.search.elasticsearch.analyzer.impl;

import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import org.hibernate.search.analyzer.impl.LazyRemoteAnalyzer;
import org.hibernate.search.analyzer.impl.RemoteAnalyzer;
import org.hibernate.search.analyzer.impl.RemoteAnalyzerReference;
import org.hibernate.search.analyzer.impl.ScopedRemoteAnalyzer;
import org.hibernate.search.analyzer.spi.AnalyzerStrategy;
import org.hibernate.search.annotations.AnalyzerDef;

Expand Down Expand Up @@ -70,4 +72,9 @@ private void initializeReference(Map<String, RemoteAnalyzer> initializedAnalyzer
private RemoteAnalyzer buildAnalyzer(String name) {
return new RemoteAnalyzer( name );
}

@Override
public ScopedRemoteAnalyzer.Builder buildScopedAnalyzer(RemoteAnalyzerReference initialGlobalAnalyzerReference) {
return new ScopedRemoteAnalyzer.Builder( initialGlobalAnalyzerReference, Collections.<String, RemoteAnalyzer>emptyMap() );
}
}
Expand Up @@ -22,6 +22,7 @@ public LuceneAnalyzerReference(Analyzer analyzer) {
this.analyzer = analyzer;
}

@Override
public Analyzer getAnalyzer() {
return analyzer;
}
Expand Down
Expand Up @@ -9,6 +9,7 @@
import java.io.IOException;
import java.text.ParseException;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

Expand All @@ -22,6 +23,7 @@
import org.hibernate.search.util.StringHelper;
import org.hibernate.search.util.impl.ClassLoaderHelper;
import org.hibernate.search.util.impl.PassThroughAnalyzer;
import org.hibernate.search.util.impl.ScopedLuceneAnalyzer;
import org.hibernate.search.util.logging.impl.Log;
import org.hibernate.search.util.logging.impl.LoggerFactory;
import org.hibernate.search.engine.service.spi.ServiceManager;
Expand Down Expand Up @@ -150,4 +152,9 @@ private Analyzer buildAnalyzer(AnalyzerDef analyzerDefinition) {
throw new SearchException( "Could not initialize Analyzer definition " + analyzerDefinition, e );
}
}

@Override
public ScopedLuceneAnalyzer.Builder buildScopedAnalyzer(LuceneAnalyzerReference initialGlobalAnalyzerReference) {
return new ScopedLuceneAnalyzer.Builder( initialGlobalAnalyzerReference, Collections.<String, Analyzer>emptyMap() );
}
}
Expand Up @@ -14,14 +14,15 @@
* @author Davide D'Alto
* @author Guillaume Smet
*/
public final class RemoteAnalyzerReference implements AnalyzerReference {
public class RemoteAnalyzerReference implements AnalyzerReference {

private RemoteAnalyzer analyzer;

public RemoteAnalyzerReference(RemoteAnalyzer analyzer) {
this.analyzer = analyzer;
}

@Override
public RemoteAnalyzer getAnalyzer() {
return analyzer;
}
Expand Down

This file was deleted.

@@ -0,0 +1,32 @@
/*
* 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.analyzer.impl;

import org.hibernate.search.analyzer.spi.AnalyzerReference;
import org.hibernate.search.analyzer.spi.ScopedAnalyzerReference;
import org.hibernate.search.util.impl.ScopedLuceneAnalyzer;

/**
* @author Yoann Rodiere
*/
public class ScopedLuceneAnalyzerReference extends LuceneAnalyzerReference implements ScopedAnalyzerReference {

public ScopedLuceneAnalyzerReference(ScopedLuceneAnalyzer analyzer) {
super( analyzer );
}

@Override
public ScopedLuceneAnalyzer getAnalyzer() {
return (ScopedLuceneAnalyzer) super.getAnalyzer();
}

@Override
public <T extends AnalyzerReference> boolean is(Class<T> analyzerType) {
return analyzerType.isAssignableFrom( ScopedLuceneAnalyzerReference.class );
}

}
Expand Up @@ -6,11 +6,11 @@
*/
package org.hibernate.search.analyzer.impl;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import org.hibernate.search.analyzer.spi.AnalyzerReference;
import org.hibernate.search.analyzer.spi.ScopedAnalyzer;
import org.hibernate.search.util.logging.impl.Log;
import org.hibernate.search.util.logging.impl.LoggerFactory;

Expand All @@ -26,53 +26,74 @@ public class ScopedRemoteAnalyzer extends RemoteAnalyzer implements ScopedAnalyz

private static final Log log = LoggerFactory.make();

private RemoteAnalyzer globalAnalyzer;
private final RemoteAnalyzerReference globalAnalyzerReference;
private final Map<String, RemoteAnalyzer> scopedAnalyzers = new HashMap<>();

public ScopedRemoteAnalyzer(AnalyzerReference globalAnalyzerReference) {
this( getRemoteAnalyzer( globalAnalyzerReference ), Collections.<String, RemoteAnalyzer>emptyMap() );
public ScopedRemoteAnalyzer(RemoteAnalyzerReference globalAnalyzerReference) {
super( globalAnalyzerReference.getAnalyzer().name );
this.globalAnalyzerReference = globalAnalyzerReference;
}

private ScopedRemoteAnalyzer(RemoteAnalyzer globalAnalyzer, Map<String, RemoteAnalyzer> analyzers) {
super( globalAnalyzer.name );
this.globalAnalyzer = globalAnalyzer;
this.scopedAnalyzers.putAll( analyzers );
}

@Override
public void setGlobalAnalyzerReference(AnalyzerReference globalAnalyzerReference) {
RemoteAnalyzer remoteAnalyzer = getRemoteAnalyzer( globalAnalyzerReference );
this.name = remoteAnalyzer.name;
this.globalAnalyzer = remoteAnalyzer;
}

@Override
public void addScopedAnalyzerReference(String scope, AnalyzerReference analyzerReference) {
this.scopedAnalyzers.put( scope, getRemoteAnalyzer( analyzerReference ) );
public ScopedRemoteAnalyzer(Builder builder) {
super( builder.globalAnalyzerReference.getAnalyzer().name );
this.globalAnalyzerReference = builder.globalAnalyzerReference;
this.scopedAnalyzers.putAll( builder.scopedAnalyzers );
}

@Override
public String getName(String fieldName) {
final RemoteAnalyzer analyzer = scopedAnalyzers.get( fieldName );
if ( analyzer == null ) {
return globalAnalyzer.getName( fieldName );
return globalAnalyzerReference.getAnalyzer().getName( fieldName );
}
else {
return analyzer.getName( fieldName );
}
}

@Override
public ScopedAnalyzer clone() {
return new ScopedRemoteAnalyzer( globalAnalyzer, scopedAnalyzers );
public Builder startCopy() {
return new Builder( globalAnalyzerReference, scopedAnalyzers );
}

public static class Builder implements ScopedAnalyzer.Builder {

private RemoteAnalyzerReference globalAnalyzerReference;
private final Map<String, RemoteAnalyzer> scopedAnalyzers = new HashMap<>();

public Builder(RemoteAnalyzerReference globalAnalyzerReference, Map<String, RemoteAnalyzer> scopedAnalyzers) {
this.globalAnalyzerReference = globalAnalyzerReference;
this.scopedAnalyzers.putAll( scopedAnalyzers );
}

@Override
public RemoteAnalyzerReference getGlobalAnalyzerReference() {
return globalAnalyzerReference;
}

@Override
public void setGlobalAnalyzerReference(AnalyzerReference globalAnalyzerReference) {
this.globalAnalyzerReference = getRemoteAnalyzerReference( globalAnalyzerReference );
}

@Override
public void addAnalyzerReference(String scope, AnalyzerReference analyzerReference) {
scopedAnalyzers.put( scope, getRemoteAnalyzerReference( analyzerReference ).getAnalyzer() );
}

@Override
public ScopedRemoteAnalyzerReference build() {
ScopedRemoteAnalyzer analyzer = new ScopedRemoteAnalyzer( this );
return new ScopedRemoteAnalyzerReference( analyzer );
}
}

private static RemoteAnalyzer getRemoteAnalyzer(AnalyzerReference analyzerReference) {
if ( !( analyzerReference instanceof RemoteAnalyzerReference ) ) {
private static RemoteAnalyzerReference getRemoteAnalyzerReference(AnalyzerReference analyzerReference) {
if ( !analyzerReference.is( RemoteAnalyzerReference.class ) ) {
throw log.analyzerReferenceIsNotRemote( analyzerReference );
}

return ( (RemoteAnalyzerReference) analyzerReference ).getAnalyzer();
return analyzerReference.unwrap( RemoteAnalyzerReference.class );
}

}
@@ -0,0 +1,31 @@
/*
* 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.analyzer.impl;

import org.hibernate.search.analyzer.spi.AnalyzerReference;
import org.hibernate.search.analyzer.spi.ScopedAnalyzerReference;

/**
* @author Yoann Rodiere
*/
public class ScopedRemoteAnalyzerReference extends RemoteAnalyzerReference implements ScopedAnalyzerReference {

public ScopedRemoteAnalyzerReference(ScopedRemoteAnalyzer analyzer) {
super( analyzer );
}

@Override
public ScopedRemoteAnalyzer getAnalyzer() {
return (ScopedRemoteAnalyzer) super.getAnalyzer();
}

@Override
public <T extends AnalyzerReference> boolean is(Class<T> analyzerType) {
return analyzerType.isAssignableFrom( ScopedRemoteAnalyzerReference.class );
}

}
Expand Up @@ -16,6 +16,11 @@
*/
public interface AnalyzerReference {

/**
* @return The referenced analyzer.
*/
Object getAnalyzer();

/**
* Check if the analyzer can be represented using a specific class.
*
Expand Down
Expand Up @@ -51,4 +51,9 @@ public interface AnalyzerStrategy<T extends AnalyzerReference> {
*/
void initializeNamedAnalyzerReferences(Collection<T> references, Map<String, AnalyzerDef> analyzerDefinitions);

/**
* @return A {@link ScopedAnalyzer} builder.
*/
ScopedAnalyzer.Builder buildScopedAnalyzer(T initialGlobalAnalyzerReference);

}
@@ -0,0 +1,45 @@
/*
* 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.analyzer.spi;

/**
* General interface for scope aware analyzers.
*
* @author Guillaume Smet
* @author Yoann Rodiere
*
* @hsearch.experimental This type is under active development as part of the Elasticsearch integration. You
* should be prepared for incompatible changes in future releases.
*/
public interface ScopedAnalyzer {

void close();

/**
* @return A builder for copying the referenced analyzer, altering some scopes as necessary.
*/
Builder startCopy();

/**
* Interface for building scope aware analyzers.
*
* @author Guillaume Smet
* @author Yoann Rodiere
* @hsearch.experimental This type is under active development as part of the Elasticsearch integration. You
* should be prepared for incompatible changes in future releases.
*/
public interface Builder {
AnalyzerReference getGlobalAnalyzerReference();

void setGlobalAnalyzerReference(AnalyzerReference globalAnalyzerReference);

void addAnalyzerReference(String scope, AnalyzerReference analyzerReference);

ScopedAnalyzerReference build();
}

}
@@ -0,0 +1,22 @@
/*
* 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.analyzer.spi;

/**
* Reference to a scoped analyzer implementation.
*
* @author Davide D'Alto
*
* @hsearch.experimental This type is under active development as part of the Elasticsearch integration. You
* should be prepared for incompatible changes in future releases.
*/
public interface ScopedAnalyzerReference extends AnalyzerReference {

@Override
ScopedAnalyzer getAnalyzer();

}
Expand Up @@ -16,9 +16,9 @@
import org.apache.lucene.index.Term;
import org.apache.lucene.search.Query;
import org.hibernate.search.analyzer.impl.LuceneAnalyzerReference;
import org.hibernate.search.analyzer.spi.ScopedAnalyzerReference;
import org.hibernate.search.backend.impl.lucene.analysis.ConcurrentlyMutableAnalyzer;
import org.hibernate.search.util.impl.ScopedLuceneAnalyzer;
import org.hibernate.search.util.impl.ScopedAnalyzerReference;

/**
* Encapsulates various operations to be performed on a single IndexWriter.
Expand Down

0 comments on commit 16f7a5d

Please sign in to comment.