Index: lucene/CHANGES.txt =================================================================== --- lucene/CHANGES.txt (revision 1508466) +++ lucene/CHANGES.txt (working copy) @@ -84,6 +84,9 @@ FacetRequest which implements createFacetsAggregator and was indexed using the taxonomy index. (Shai Erera) +* LUCENE-5153: AnalyzerWrapper.wrapReader allows wrapping the Reader given to + inputReader. (Shai Erera) + Bug Fixes * LUCENE-5116: IndexWriter.addIndexes(IndexReader...) should drop empty (or all Index: lucene/analysis/common/src/java/org/apache/lucene/analysis/miscellaneous/PerFieldAnalyzerWrapper.java =================================================================== --- lucene/analysis/common/src/java/org/apache/lucene/analysis/miscellaneous/PerFieldAnalyzerWrapper.java (revision 1508466) +++ lucene/analysis/common/src/java/org/apache/lucene/analysis/miscellaneous/PerFieldAnalyzerWrapper.java (working copy) @@ -84,11 +84,6 @@ } @Override - protected TokenStreamComponents wrapComponents(String fieldName, TokenStreamComponents components) { - return components; - } - - @Override public String toString() { return "PerFieldAnalyzerWrapper(" + fieldAnalyzers + ", default=" + defaultAnalyzer + ")"; } Index: lucene/core/src/java/org/apache/lucene/analysis/AnalyzerWrapper.java =================================================================== --- lucene/core/src/java/org/apache/lucene/analysis/AnalyzerWrapper.java (revision 1508466) +++ lucene/core/src/java/org/apache/lucene/analysis/AnalyzerWrapper.java (working copy) @@ -51,16 +51,35 @@ /** * Wraps / alters the given TokenStreamComponents, taken from the wrapped - * Analyzer, to form new components. It is through this method that new - * TokenFilters can be added by AnalyzerWrappers. - * - * - * @param fieldName Name of the field which is to be analyzed - * @param components TokenStreamComponents taken from the wrapped Analyzer + * Analyzer, to form new components. It is through this method that new + * TokenFilters can be added by AnalyzerWrappers. By default, the given + * components are returned. + * + * @param fieldName + * Name of the field which is to be analyzed + * @param components + * TokenStreamComponents taken from the wrapped Analyzer * @return Wrapped / altered TokenStreamComponents. */ - protected abstract TokenStreamComponents wrapComponents(String fieldName, TokenStreamComponents components); + protected TokenStreamComponents wrapComponents(String fieldName, TokenStreamComponents components) { + return components; + } + /** + * Wraps / alters the given Reader. Through this method AnalyzerWrappers can + * implement {@link #initReader(String, Reader)}. By default, the given reader + * is returned. + * + * @param fieldName + * name of the field which is to be analyzed + * @param reader + * the reader to wrap + * @return the wrapped reader + */ + protected Reader wrapReader(String fieldName, Reader reader) { + return reader; + } + @Override protected final TokenStreamComponents createComponents(String fieldName, Reader aReader) { return wrapComponents(fieldName, getWrappedAnalyzer(fieldName).createComponents(fieldName, aReader)); @@ -78,6 +97,6 @@ @Override public final Reader initReader(String fieldName, Reader reader) { - return getWrappedAnalyzer(fieldName).initReader(fieldName, reader); + return getWrappedAnalyzer(fieldName).initReader(fieldName, wrapReader(fieldName, reader)); } } Index: lucene/core/src/test/org/apache/lucene/analysis/TestMockAnalyzer.java =================================================================== --- lucene/core/src/test/org/apache/lucene/analysis/TestMockAnalyzer.java (revision 1508466) +++ lucene/core/src/test/org/apache/lucene/analysis/TestMockAnalyzer.java (working copy) @@ -1,8 +1,11 @@ package org.apache.lucene.analysis; +import java.io.Reader; import java.io.StringReader; import java.util.Arrays; +import java.util.Random; +import org.apache.lucene.analysis.tokenattributes.CharTermAttribute; import org.apache.lucene.util._TestUtil; import org.apache.lucene.util.automaton.Automaton; import org.apache.lucene.util.automaton.BasicAutomata; @@ -128,4 +131,34 @@ ts.close(); } } + + public void testWrapReader() throws Exception { + // LUCENE-5153: test that wrapping an analyzer's reader is allowed + final Random random = random(); + + Analyzer a = new AnalyzerWrapper() { + + @Override + protected Reader wrapReader(String fieldName, Reader reader) { + return new MockCharFilter(reader, 7); + } + + @Override + protected TokenStreamComponents wrapComponents(String fieldName, TokenStreamComponents components) { + return components; + } + + @Override + protected Analyzer getWrappedAnalyzer(String fieldName) { + return new MockAnalyzer(random); + } + }; + + TokenStream ts = a.tokenStream("", "abc"); + CharTermAttribute term = ts.addAttribute(CharTermAttribute.class); + ts.reset(); + assertTrue(ts.incrementToken()); + assertEquals("aabc", term.toString()); + assertFalse(ts.incrementToken()); + } } Index: solr/core/src/java/org/apache/solr/schema/IndexSchema.java =================================================================== --- solr/core/src/java/org/apache/solr/schema/IndexSchema.java (revision 1508466) +++ solr/core/src/java/org/apache/solr/schema/IndexSchema.java (working copy) @@ -397,10 +397,6 @@ return analyzer != null ? analyzer : getDynamicFieldType(fieldName).getAnalyzer(); } - @Override - protected TokenStreamComponents wrapComponents(String fieldName, TokenStreamComponents components) { - return components; - } } private class SolrQueryAnalyzer extends SolrIndexAnalyzer {