Index: backwards/src/test/org/apache/lucene/analysis/TestAnalyzers.java =================================================================== --- backwards/src/test/org/apache/lucene/analysis/TestAnalyzers.java (revision 932749) +++ backwards/src/test/org/apache/lucene/analysis/TestAnalyzers.java (working copy) @@ -143,7 +143,7 @@ */ } -class PayloadSetter extends TokenFilter { +final class PayloadSetter extends TokenFilter { PayloadAttribute payloadAtt; public PayloadSetter(TokenStream input) { super(input); Index: backwards/src/test/org/apache/lucene/queryParser/TestQueryParser.java =================================================================== --- backwards/src/test/org/apache/lucene/queryParser/TestQueryParser.java (revision 932749) +++ backwards/src/test/org/apache/lucene/queryParser/TestQueryParser.java (working copy) @@ -81,7 +81,7 @@ public static Analyzer qpAnalyzer = new QPTestAnalyzer(); - public static class QPTestFilter extends TokenFilter { + public static final class QPTestFilter extends TokenFilter { TermAttribute termAtt; OffsetAttribute offsetAtt; @@ -122,7 +122,7 @@ } - public static class QPTestAnalyzer extends Analyzer { + public static final class QPTestAnalyzer extends Analyzer { /** Filters LowerCaseTokenizer with StopFilter. */ @Override Index: backwards/src/test/org/apache/lucene/search/payloads/PayloadHelper.java =================================================================== --- backwards/src/test/org/apache/lucene/search/payloads/PayloadHelper.java (revision 932749) +++ backwards/src/test/org/apache/lucene/search/payloads/PayloadHelper.java (working copy) @@ -44,7 +44,7 @@ public static final String MULTI_FIELD = "multiField"; public static final String FIELD = "field"; - public class PayloadAnalyzer extends Analyzer { + public final class PayloadAnalyzer extends Analyzer { @@ -56,7 +56,7 @@ } } - public class PayloadFilter extends TokenFilter { + public final class PayloadFilter extends TokenFilter { String fieldName; int numSeen = 0; PayloadAttribute payloadAtt; Index: backwards/src/test/org/apache/lucene/search/spans/TestPayloadSpans.java =================================================================== --- backwards/src/test/org/apache/lucene/search/spans/TestPayloadSpans.java (revision 932749) +++ backwards/src/test/org/apache/lucene/search/spans/TestPayloadSpans.java (working copy) @@ -471,7 +471,7 @@ assertEquals(numSpans, cnt); } - class PayloadAnalyzer extends Analyzer { + final class PayloadAnalyzer extends Analyzer { @Override public TokenStream tokenStream(String fieldName, Reader reader) { @@ -481,7 +481,7 @@ } } - class PayloadFilter extends TokenFilter { + final class PayloadFilter extends TokenFilter { String fieldName; int numSeen = 0; Set entities = new HashSet(); @@ -523,7 +523,7 @@ } } - public class TestPayloadAnalyzer extends Analyzer { + public final class TestPayloadAnalyzer extends Analyzer { @Override public TokenStream tokenStream(String fieldName, Reader reader) { Index: backwards/src/test/org/apache/lucene/search/TestPositionIncrement.java =================================================================== --- backwards/src/test/org/apache/lucene/search/TestPositionIncrement.java (revision 932749) +++ backwards/src/test/org/apache/lucene/search/TestPositionIncrement.java (working copy) @@ -317,7 +317,7 @@ } } -class TestPayloadAnalyzer extends Analyzer { +final class TestPayloadAnalyzer extends Analyzer { @Override public TokenStream tokenStream(String fieldName, Reader reader) { @@ -326,7 +326,7 @@ } } -class PayloadFilter extends TokenFilter { +final class PayloadFilter extends TokenFilter { String fieldName; int pos; Index: CHANGES.txt =================================================================== --- CHANGES.txt (revision 932749) +++ CHANGES.txt (working copy) @@ -97,9 +97,13 @@ TODO: Point to new attribute inspection API coming with LUCENE-2374. (Uwe Schindler, Robert Muir) -* LUCENE-2372: StandardAnalyzer, KeywordAnalyzer, PerFieldAnalyzerWrapper - are now final. Also removed the now obsolete and deprecated - Analyzer.setOverridesTokenStreamMethod(). (Uwe Schindler) +* LUCENE-2372, LUCENE-2389: StandardAnalyzer, KeywordAnalyzer, + PerFieldAnalyzerWrapper, WhitespaceTokenizer are now final. Also removed + the now obsolete and deprecated Analyzer.setOverridesTokenStreamMethod(). + Analyzer and TokenStream base classes now have an assertion in their ctor, + that check subclasses to be final or at least have final implementations + of incrementToken(), tokenStream(), and reusableTokenStream(). + (Uwe Schindler, Robert Muir) Changes in runtime behavior Index: contrib/analyzers/common/src/test/org/apache/lucene/analysis/shingle/TestShingleMatrixFilter.java =================================================================== --- contrib/analyzers/common/src/test/org/apache/lucene/analysis/shingle/TestShingleMatrixFilter.java (revision 932749) +++ contrib/analyzers/common/src/test/org/apache/lucene/analysis/shingle/TestShingleMatrixFilter.java (working copy) @@ -482,7 +482,7 @@ } - public static class TokenListStream extends TokenStream { + public final static class TokenListStream extends TokenStream { private Collection tokens; TermAttribute termAtt; Index: contrib/highlighter/src/java/org/apache/lucene/search/highlight/TokenSources.java =================================================================== --- contrib/highlighter/src/java/org/apache/lucene/search/highlight/TokenSources.java (revision 932749) +++ contrib/highlighter/src/java/org/apache/lucene/search/highlight/TokenSources.java (working copy) @@ -148,7 +148,7 @@ } // an object used to iterate across an array of tokens - class StoredTokenStream extends TokenStream { + final class StoredTokenStream extends TokenStream { Token tokens[]; int currentToken = 0; Index: contrib/highlighter/src/java/org/apache/lucene/search/highlight/TokenStreamFromTermPositionVector.java =================================================================== --- contrib/highlighter/src/java/org/apache/lucene/search/highlight/TokenStreamFromTermPositionVector.java (revision 932749) +++ contrib/highlighter/src/java/org/apache/lucene/search/highlight/TokenStreamFromTermPositionVector.java (working copy) @@ -31,10 +31,7 @@ import org.apache.lucene.index.TermPositionVector; import org.apache.lucene.index.TermVectorOffsetInfo; -/** - * @author CMorris - */ -public class TokenStreamFromTermPositionVector extends TokenStream { +public final class TokenStreamFromTermPositionVector extends TokenStream { private final List positionedTokens = new ArrayList(); Index: contrib/highlighter/src/test/org/apache/lucene/search/highlight/HighlighterTest.java =================================================================== --- contrib/highlighter/src/test/org/apache/lucene/search/highlight/HighlighterTest.java (revision 932749) +++ contrib/highlighter/src/test/org/apache/lucene/search/highlight/HighlighterTest.java (working copy) @@ -1783,7 +1783,7 @@ // behaviour to synonyms // =================================================================== -class SynonymAnalyzer extends Analyzer { +final class SynonymAnalyzer extends Analyzer { private Map synonyms; public SynonymAnalyzer(Map synonyms) { @@ -1810,7 +1810,7 @@ * Expands a token stream with synonyms (TODO - make the synonyms analyzed by choice of analyzer) * */ -class SynonymTokenizer extends TokenStream { +final class SynonymTokenizer extends TokenStream { private TokenStream realStream; private Token currentRealToken = null; private Map synonyms; Index: contrib/highlighter/src/test/org/apache/lucene/search/vectorhighlight/AbstractTestCase.java =================================================================== --- contrib/highlighter/src/test/org/apache/lucene/search/vectorhighlight/AbstractTestCase.java (revision 932749) +++ contrib/highlighter/src/test/org/apache/lucene/search/vectorhighlight/AbstractTestCase.java (working copy) @@ -170,14 +170,14 @@ } } - static class BigramAnalyzer extends Analyzer { + static final class BigramAnalyzer extends Analyzer { @Override public TokenStream tokenStream(String fieldName, Reader reader) { return new BasicNGramTokenizer( reader ); } } - static class BasicNGramTokenizer extends Tokenizer { + static final class BasicNGramTokenizer extends Tokenizer { public static final int DEFAULT_N_SIZE = 2; public static final String DEFAULT_DELIMITERS = " \t\n.,"; Index: contrib/highlighter/src/test/org/apache/lucene/search/vectorhighlight/IndexTimeSynonymTest.java =================================================================== --- contrib/highlighter/src/test/org/apache/lucene/search/vectorhighlight/IndexTimeSynonymTest.java (revision 932749) +++ contrib/highlighter/src/test/org/apache/lucene/search/vectorhighlight/IndexTimeSynonymTest.java (working copy) @@ -292,7 +292,7 @@ return token; } - public static class TokenArrayAnalyzer extends Analyzer { + public static final class TokenArrayAnalyzer extends Analyzer { Token[] tokens; public TokenArrayAnalyzer( Token... tokens ){ this.tokens = tokens; Index: contrib/icu/src/test/org/apache/lucene/collation/TestICUCollationKeyFilter.java =================================================================== --- contrib/icu/src/test/org/apache/lucene/collation/TestICUCollationKeyFilter.java (revision 932749) +++ contrib/icu/src/test/org/apache/lucene/collation/TestICUCollationKeyFilter.java (working copy) @@ -42,7 +42,7 @@ (collator.getCollationKey(secondRangeEndOriginal).toByteArray()); - public class TestAnalyzer extends Analyzer { + public final class TestAnalyzer extends Analyzer { private Collator _collator; TestAnalyzer(Collator collator) { Index: contrib/queryparser/src/test/org/apache/lucene/queryParser/analyzing/TestAnalyzingQueryParser.java =================================================================== --- contrib/queryparser/src/test/org/apache/lucene/queryParser/analyzing/TestAnalyzingQueryParser.java (revision 932749) +++ contrib/queryparser/src/test/org/apache/lucene/queryParser/analyzing/TestAnalyzingQueryParser.java (working copy) @@ -105,7 +105,7 @@ } -class ASCIIAnalyzer extends org.apache.lucene.analysis.Analyzer { +final class ASCIIAnalyzer extends org.apache.lucene.analysis.Analyzer { public ASCIIAnalyzer() { } Index: contrib/queryparser/src/test/org/apache/lucene/queryParser/precedence/TestPrecedenceQueryParser.java =================================================================== --- contrib/queryparser/src/test/org/apache/lucene/queryParser/precedence/TestPrecedenceQueryParser.java (revision 932749) +++ contrib/queryparser/src/test/org/apache/lucene/queryParser/precedence/TestPrecedenceQueryParser.java (working copy) @@ -56,7 +56,7 @@ public static Analyzer qpAnalyzer = new QPTestAnalyzer(); - public static class QPTestFilter extends TokenFilter { + public static final class QPTestFilter extends TokenFilter { /** * Filter which discards the token 'stop' and which expands the * token 'phrase' into 'phrase1 phrase2' @@ -94,7 +94,7 @@ } } - public static class QPTestAnalyzer extends Analyzer { + public static final class QPTestAnalyzer extends Analyzer { /** Filters LowerCaseTokenizer with StopFilter. */ @Override Index: contrib/queryparser/src/test/org/apache/lucene/queryParser/standard/TestMultiFieldQPHelper.java =================================================================== --- contrib/queryparser/src/test/org/apache/lucene/queryParser/standard/TestMultiFieldQPHelper.java (revision 932749) +++ contrib/queryparser/src/test/org/apache/lucene/queryParser/standard/TestMultiFieldQPHelper.java (working copy) @@ -342,7 +342,7 @@ /** * Return empty tokens for field "f1". */ - private static class AnalyzerReturningNull extends Analyzer { + private static final class AnalyzerReturningNull extends Analyzer { StandardAnalyzer stdAnalyzer = new StandardAnalyzer(TEST_VERSION_CURRENT); public AnalyzerReturningNull() { Index: contrib/queryparser/src/test/org/apache/lucene/queryParser/standard/TestQPHelper.java =================================================================== --- contrib/queryparser/src/test/org/apache/lucene/queryParser/standard/TestQPHelper.java (revision 932749) +++ contrib/queryparser/src/test/org/apache/lucene/queryParser/standard/TestQPHelper.java (working copy) @@ -97,7 +97,7 @@ public static Analyzer qpAnalyzer = new QPTestAnalyzer(); - public static class QPTestFilter extends TokenFilter { + public static final class QPTestFilter extends TokenFilter { TermAttribute termAtt; OffsetAttribute offsetAtt; @@ -138,7 +138,7 @@ } } - public static class QPTestAnalyzer extends Analyzer { + public static final class QPTestAnalyzer extends Analyzer { /** Filters LowerCaseTokenizer with StopFilter. */ @Override Index: contrib/queryparser/src/test/org/apache/lucene/queryParser/standard/TestQueryParserWrapper.java =================================================================== --- contrib/queryparser/src/test/org/apache/lucene/queryParser/standard/TestQueryParserWrapper.java (revision 932749) +++ contrib/queryparser/src/test/org/apache/lucene/queryParser/standard/TestQueryParserWrapper.java (working copy) @@ -94,7 +94,7 @@ public static Analyzer qpAnalyzer = new QPTestAnalyzer(); - public static class QPTestFilter extends TokenFilter { + public static final class QPTestFilter extends TokenFilter { TermAttribute termAtt; OffsetAttribute offsetAtt; @@ -135,7 +135,7 @@ } } - public static class QPTestAnalyzer extends Analyzer { + public static final class QPTestAnalyzer extends Analyzer { /** Filters LowerCaseTokenizer with StopFilter. */ @Override Index: src/java/org/apache/lucene/analysis/Analyzer.java =================================================================== --- src/java/org/apache/lucene/analysis/Analyzer.java (revision 932749) +++ src/java/org/apache/lucene/analysis/Analyzer.java (working copy) @@ -20,9 +20,9 @@ import java.io.Reader; import java.io.IOException; import java.io.Closeable; +import java.lang.reflect.Modifier; import org.apache.lucene.util.CloseableThreadLocal; -import org.apache.lucene.util.VirtualMethod; import org.apache.lucene.store.AlreadyClosedException; import org.apache.lucene.document.Fieldable; @@ -33,8 +33,34 @@ * Typical implementations first build a Tokenizer, which breaks the stream of * characters from the Reader into raw Tokens. One or more TokenFilters may * then be applied to the output of the Tokenizer. + *

The {@code Analyzer}-API in Lucene is based on the decorator pattern. + * Therefore all non-abstract subclasses must be final or their {@link #tokenStream} + * and {@link #reusableTokenStream} implementations must be final! This is checked + * when Java assertions are enabled. */ public abstract class Analyzer implements Closeable { + + protected Analyzer() { + super(); + assert assertFinal(); + } + + private boolean assertFinal() { + try { + final Class clazz = getClass(); + assert clazz.isAnonymousClass() || + (clazz.getModifiers() & (Modifier.FINAL | Modifier.PRIVATE)) != 0 || + ( + Modifier.isFinal(clazz.getMethod("tokenStream", String.class, Reader.class).getModifiers()) && + Modifier.isFinal(clazz.getMethod("reusableTokenStream", String.class, Reader.class).getModifiers()) + ) : + "Analyzer implementation classes or at least their tokenStream() and reusableTokenStream() implementations must be final"; + return true; + } catch (NoSuchMethodException nsme) { + return false; + } + } + /** Creates a TokenStream which tokenizes all the text in the provided * Reader. Must be able to handle null field name for * backward compatibility. Index: src/java/org/apache/lucene/analysis/TokenStream.java =================================================================== --- src/java/org/apache/lucene/analysis/TokenStream.java (revision 932749) +++ src/java/org/apache/lucene/analysis/TokenStream.java (working copy) @@ -19,6 +19,7 @@ import java.io.IOException; import java.io.Closeable; +import java.lang.reflect.Modifier; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; @@ -76,6 +77,10 @@ * {@link TeeSinkTokenFilter}). For this usecase * {@link AttributeSource#captureState} and {@link AttributeSource#restoreState} * can be used. + *

The {@code TokenStream}-API in Lucene is based on the decorator pattern. + * Therefore all non-abstract subclasses must be final or have at least a final + * implementation of {@link #incrementToken}! This is checked when Java + * assertions are enabled. */ public abstract class TokenStream extends AttributeSource implements Closeable { @@ -84,6 +89,7 @@ */ protected TokenStream() { super(); + assert assertFinal(); } /** @@ -91,6 +97,7 @@ */ protected TokenStream(AttributeSource input) { super(input); + assert assertFinal(); } /** @@ -98,8 +105,22 @@ */ protected TokenStream(AttributeFactory factory) { super(factory); + assert assertFinal(); } + private boolean assertFinal() { + try { + final Class clazz = getClass(); + assert clazz.isAnonymousClass() || + (clazz.getModifiers() & (Modifier.FINAL | Modifier.PRIVATE)) != 0 || + Modifier.isFinal(clazz.getMethod("incrementToken").getModifiers()) : + "TokenStream implementation classes or at least their incrementToken() implementation must be final"; + return true; + } catch (NoSuchMethodException nsme) { + return false; + } + } + /** * Consumers (i.e., {@link IndexWriter}) use this method to advance the stream to * the next token. Implementing classes must implement this method and update Index: src/java/org/apache/lucene/analysis/WhitespaceTokenizer.java =================================================================== --- src/java/org/apache/lucene/analysis/WhitespaceTokenizer.java (revision 932749) +++ src/java/org/apache/lucene/analysis/WhitespaceTokenizer.java (working copy) @@ -35,7 +35,7 @@ * {@link CharTokenizer#normalize(int)} for details. * */ -public class WhitespaceTokenizer extends CharTokenizer { +public final class WhitespaceTokenizer extends CharTokenizer { /** * Construct a new WhitespaceTokenizer. * @param matchVersion Lucene version Index: src/java/org/apache/lucene/collation/CollationKeyAnalyzer.java =================================================================== --- src/java/org/apache/lucene/collation/CollationKeyAnalyzer.java (revision 932749) +++ src/java/org/apache/lucene/collation/CollationKeyAnalyzer.java (working copy) @@ -76,7 +76,7 @@ * ICUCollationKeyAnalyzer on the query side, or vice versa. *

*/ -public class CollationKeyAnalyzer extends Analyzer { +public final class CollationKeyAnalyzer extends Analyzer { private Collator collator; public CollationKeyAnalyzer(Collator collator) { Index: src/test/org/apache/lucene/analysis/TestAnalyzers.java =================================================================== --- src/test/org/apache/lucene/analysis/TestAnalyzers.java (revision 932749) +++ src/test/org/apache/lucene/analysis/TestAnalyzers.java (working copy) @@ -216,7 +216,7 @@ } -class PayloadSetter extends TokenFilter { +final class PayloadSetter extends TokenFilter { PayloadAttribute payloadAtt; public PayloadSetter(TokenStream input) { super(input); Index: src/test/org/apache/lucene/analysis/TestCharTokenizers.java =================================================================== --- src/test/org/apache/lucene/analysis/TestCharTokenizers.java (revision 932749) +++ src/test/org/apache/lucene/analysis/TestCharTokenizers.java (working copy) @@ -162,7 +162,7 @@ } } - static class TestingCharTokenizer extends CharTokenizer { + static final class TestingCharTokenizer extends CharTokenizer { public TestingCharTokenizer(Version matchVersion, Reader input) { super(matchVersion, input); } @@ -178,7 +178,7 @@ } } - static class TestingCharTokenizerNormalize extends CharTokenizer { + static final class TestingCharTokenizerNormalize extends CharTokenizer { public TestingCharTokenizerNormalize(Version matchVersion, Reader input) { super(matchVersion, input); } @@ -194,7 +194,7 @@ } } - static class TestingCharTokenizerNormalizeIsTokenChar extends CharTokenizer { + static final class TestingCharTokenizerNormalizeIsTokenChar extends CharTokenizer { public TestingCharTokenizerNormalizeIsTokenChar(Version matchVersion, Reader input) { super(matchVersion, input); Index: src/test/org/apache/lucene/analysis/TestKeywordMarkerTokenFilter.java =================================================================== --- src/test/org/apache/lucene/analysis/TestKeywordMarkerTokenFilter.java (revision 932749) +++ src/test/org/apache/lucene/analysis/TestKeywordMarkerTokenFilter.java (working copy) @@ -51,7 +51,7 @@ "The quIck browN LuceneFox Jumps")), set2)), output); } - public static class LowerCaseFilterMock extends TokenFilter { + public static final class LowerCaseFilterMock extends TokenFilter { private final CharTermAttribute termAtt = addAttribute(CharTermAttribute.class); private final KeywordAttribute keywordAttr = addAttribute(KeywordAttribute.class); Index: src/test/org/apache/lucene/collation/TestCollationKeyFilter.java =================================================================== --- src/test/org/apache/lucene/collation/TestCollationKeyFilter.java (revision 932749) +++ src/test/org/apache/lucene/collation/TestCollationKeyFilter.java (working copy) @@ -45,7 +45,7 @@ (collator.getCollationKey(secondRangeEndOriginal).toByteArray()); - public class TestAnalyzer extends Analyzer { + public final class TestAnalyzer extends Analyzer { private Collator _collator; TestAnalyzer(Collator collator) { Index: src/test/org/apache/lucene/queryParser/TestQueryParser.java =================================================================== --- src/test/org/apache/lucene/queryParser/TestQueryParser.java (revision 932749) +++ src/test/org/apache/lucene/queryParser/TestQueryParser.java (working copy) @@ -81,7 +81,7 @@ public static Analyzer qpAnalyzer = new QPTestAnalyzer(); - public static class QPTestFilter extends TokenFilter { + public static final class QPTestFilter extends TokenFilter { CharTermAttribute termAtt; OffsetAttribute offsetAtt; @@ -123,7 +123,7 @@ } - public static class QPTestAnalyzer extends Analyzer { + public static final class QPTestAnalyzer extends Analyzer { /** Filters LowerCaseTokenizer with StopFilter. */ @Override Index: src/test/org/apache/lucene/search/payloads/PayloadHelper.java =================================================================== --- src/test/org/apache/lucene/search/payloads/PayloadHelper.java (revision 932749) +++ src/test/org/apache/lucene/search/payloads/PayloadHelper.java (working copy) @@ -46,7 +46,7 @@ public static final String MULTI_FIELD = "multiField"; public static final String FIELD = "field"; - public class PayloadAnalyzer extends Analyzer { + public final class PayloadAnalyzer extends Analyzer { @@ -58,7 +58,7 @@ } } - public class PayloadFilter extends TokenFilter { + public final class PayloadFilter extends TokenFilter { String fieldName; int numSeen = 0; PayloadAttribute payloadAtt; Index: src/test/org/apache/lucene/search/spans/TestPayloadSpans.java =================================================================== --- src/test/org/apache/lucene/search/spans/TestPayloadSpans.java (revision 932749) +++ src/test/org/apache/lucene/search/spans/TestPayloadSpans.java (working copy) @@ -462,7 +462,7 @@ assertEquals(numSpans, cnt); } - class PayloadAnalyzer extends Analyzer { + final class PayloadAnalyzer extends Analyzer { @Override public TokenStream tokenStream(String fieldName, Reader reader) { @@ -472,7 +472,7 @@ } } - class PayloadFilter extends TokenFilter { + final class PayloadFilter extends TokenFilter { String fieldName; int numSeen = 0; Set entities = new HashSet(); @@ -514,7 +514,7 @@ } } - public class TestPayloadAnalyzer extends Analyzer { + public final class TestPayloadAnalyzer extends Analyzer { @Override public TokenStream tokenStream(String fieldName, Reader reader) { Index: src/test/org/apache/lucene/search/TestPositionIncrement.java =================================================================== --- src/test/org/apache/lucene/search/TestPositionIncrement.java (revision 932749) +++ src/test/org/apache/lucene/search/TestPositionIncrement.java (working copy) @@ -329,7 +329,7 @@ } } -class TestPayloadAnalyzer extends Analyzer { +final class TestPayloadAnalyzer extends Analyzer { @Override public TokenStream tokenStream(String fieldName, Reader reader) { @@ -338,7 +338,7 @@ } } -class PayloadFilter extends TokenFilter { +final class PayloadFilter extends TokenFilter { String fieldName; int pos; Index: src/test/org/apache/lucene/TestAssertions.java =================================================================== --- src/test/org/apache/lucene/TestAssertions.java (revision 932749) +++ src/test/org/apache/lucene/TestAssertions.java (working copy) @@ -17,11 +17,15 @@ * limitations under the License. */ +import java.io.Reader; + import org.apache.lucene.util.LuceneTestCase; +import org.apache.lucene.analysis.Analyzer; +import org.apache.lucene.analysis.TokenStream; public class TestAssertions extends LuceneTestCase { - public void test() { + public void testBasics() { try { assert Boolean.FALSE.booleanValue(); fail("assertions are not enabled!"); @@ -29,5 +33,65 @@ assert Boolean.TRUE.booleanValue(); } } + + static class TestAnalyzer1 extends Analyzer { + public final TokenStream tokenStream(String s, Reader r) { return null; } + public final TokenStream reusableTokenStream(String s, Reader r) { return null; } + } + static final class TestAnalyzer2 extends Analyzer { + public TokenStream tokenStream(String s, Reader r) { return null; } + public TokenStream reusableTokenStream(String s, Reader r) { return null; } + } + + static class TestAnalyzer3 extends Analyzer { + public TokenStream tokenStream(String s, Reader r) { return null; } + public TokenStream reusableTokenStream(String s, Reader r) { return null; } + } + + static class TestAnalyzer4 extends Analyzer { + public final TokenStream tokenStream(String s, Reader r) { return null; } + public TokenStream reusableTokenStream(String s, Reader r) { return null; } + } + + static class TestTokenStream1 extends TokenStream { + public final boolean incrementToken() { return false; } + } + + static final class TestTokenStream2 extends TokenStream { + public boolean incrementToken() { return false; } + } + + static class TestTokenStream3 extends TokenStream { + public boolean incrementToken() { return false; } + } + + public void testTokenStreams() { + new TestAnalyzer1(); + + new TestAnalyzer2(); + + try { + new TestAnalyzer3(); + fail("TestAnalyzer3 should fail assertion"); + } catch (AssertionError e) { + } + + try { + new TestAnalyzer4(); + fail("TestAnalyzer4 should fail assertion"); + } catch (AssertionError e) { + } + + new TestTokenStream1(); + + new TestTokenStream2(); + + try { + new TestTokenStream3(); + fail("TestTokenStream3 should fail assertion"); + } catch (AssertionError e) { + } + } + }