From c1f5e753d762d68d274cb8948f8acd7cdba6a7ec Mon Sep 17 00:00:00 2001 From: Uwe Schindler Date: Thu, 1 Oct 2009 13:49:46 +0000 Subject: [PATCH] LUCENE-1933: Provide a convenience AttributeFactory that creates a Token instance for all basic attributes git-svn-id: https://svn.apache.org/repos/asf/lucene/java/trunk@820658 13f79535-47bb-0310-9956-ffa450edef68 --- CHANGES.txt | 3 ++ .../miscellaneous/SingleTokenTokenStream.java | 9 +--- .../vectorhighlight/IndexTimeSynonymTest.java | 13 +++--- .../store/instantiated/TestIndicesEquals.java | 11 +++-- .../org/apache/lucene/analysis/Token.java | 43 +++++++++++++++++++ .../apache/lucene/util/AttributeSource.java | 9 +++- 6 files changed, 67 insertions(+), 21 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index c6d14a09bac..07ed0dd9aef 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -22,6 +22,9 @@ Bug fixes New features +* LUCENE-1933: Provide a convenience AttributeFactory that creates a + Token instance for all basic attributes. (Uwe Schindler) + Optimizations Documentation diff --git a/contrib/analyzers/common/src/java/org/apache/lucene/analysis/miscellaneous/SingleTokenTokenStream.java b/contrib/analyzers/common/src/java/org/apache/lucene/analysis/miscellaneous/SingleTokenTokenStream.java index 8b9aebe1055..1c15b3ede45 100644 --- a/contrib/analyzers/common/src/java/org/apache/lucene/analysis/miscellaneous/SingleTokenTokenStream.java +++ b/contrib/analyzers/common/src/java/org/apache/lucene/analysis/miscellaneous/SingleTokenTokenStream.java @@ -35,15 +35,8 @@ public class SingleTokenTokenStream extends TokenStream { private Token singleToken; private final AttributeImpl tokenAtt; - private static final AttributeFactory TOKEN_ATTRIBUTE_FACTORY = new AttributeFactory() { - public AttributeImpl createAttributeInstance(Class attClass) { - return attClass.isAssignableFrom(Token.class) - ? new Token() : DEFAULT_ATTRIBUTE_FACTORY.createAttributeInstance(attClass); - } - }; - public SingleTokenTokenStream(Token token) { - super(TOKEN_ATTRIBUTE_FACTORY); + super(Token.TOKEN_ATTRIBUTE_FACTORY); assert token != null; this.singleToken = (Token) token.clone(); diff --git a/contrib/fast-vector-highlighter/src/test/org/apache/lucene/search/vectorhighlight/IndexTimeSynonymTest.java b/contrib/fast-vector-highlighter/src/test/org/apache/lucene/search/vectorhighlight/IndexTimeSynonymTest.java index f3634379630..40d96b631b6 100644 --- a/contrib/fast-vector-highlighter/src/test/org/apache/lucene/search/vectorhighlight/IndexTimeSynonymTest.java +++ b/contrib/fast-vector-highlighter/src/test/org/apache/lucene/search/vectorhighlight/IndexTimeSynonymTest.java @@ -25,8 +25,10 @@ import java.util.Set; import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.analysis.Token; import org.apache.lucene.analysis.TokenStream; +import org.apache.lucene.analysis.tokenattributes.TermAttribute; import org.apache.lucene.search.BooleanQuery; import org.apache.lucene.search.BooleanClause.Occur; +import org.apache.lucene.util.AttributeImpl; public class IndexTimeSynonymTest extends AbstractTestCase { @@ -296,19 +298,18 @@ public class IndexTimeSynonymTest extends AbstractTestCase { this.tokens = tokens; } - public TokenStream tokenStream(String fieldName, Reader reader) { - final Token reusableToken = new Token(); - - TokenStream.setOnlyUseNewAPI(true); - TokenStream ts = new TokenStream(){ + public TokenStream tokenStream(String fieldName, Reader reader) { + TokenStream ts = new TokenStream(Token.TOKEN_ATTRIBUTE_FACTORY) { + final AttributeImpl reusableToken = (AttributeImpl) addAttribute(TermAttribute.class); int p = 0; + public boolean incrementToken() throws IOException { if( p >= tokens.length ) return false; + clearAttributes(); tokens[p++].copyTo(reusableToken); return true; } }; - ts.addAttributeImpl(reusableToken); return ts; } } diff --git a/contrib/instantiated/src/test/org/apache/lucene/store/instantiated/TestIndicesEquals.java b/contrib/instantiated/src/test/org/apache/lucene/store/instantiated/TestIndicesEquals.java index 496fba45e63..e90960a7aa2 100644 --- a/contrib/instantiated/src/test/org/apache/lucene/store/instantiated/TestIndicesEquals.java +++ b/contrib/instantiated/src/test/org/apache/lucene/store/instantiated/TestIndicesEquals.java @@ -45,7 +45,7 @@ import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.search.TermQuery; import org.apache.lucene.search.TopDocCollector; import org.apache.lucene.search.TopScoreDocCollector; -import org.apache.lucene.util.AttributeSource; +import org.apache.lucene.util.AttributeImpl; /** * Asserts equality of content and behaviour of two index readers. @@ -177,16 +177,16 @@ public class TestIndicesEquals extends TestCase { t.setPayload(new Payload(new byte[]{2})); tokens.add(t); tokens.add(createToken("fin", 7, 9)); - final Token reusableToken = new Token(); - TokenStream ts = new TokenStream() { + TokenStream ts = new TokenStream(Token.TOKEN_ATTRIBUTE_FACTORY) { + final AttributeImpl reusableToken = (AttributeImpl) addAttribute(TermAttribute.class); Iterator it = tokens.iterator(); public final boolean incrementToken() throws IOException { if (!it.hasNext()) { return false; } - - reusableToken.reinit(it.next()); + clearAttributes(); + it.next().copyTo(reusableToken); return true; } @@ -194,7 +194,6 @@ public class TestIndicesEquals extends TestCase { it = tokens.iterator(); } }; - ts.addAttributeImpl(reusableToken); document.add(new Field("f", ts)); } diff --git a/src/java/org/apache/lucene/analysis/Token.java b/src/java/org/apache/lucene/analysis/Token.java index 67f752b13ef..a8d115cacfc 100644 --- a/src/java/org/apache/lucene/analysis/Token.java +++ b/src/java/org/apache/lucene/analysis/Token.java @@ -27,6 +27,7 @@ import org.apache.lucene.index.Payload; import org.apache.lucene.index.TermPositions; // for javadoc import org.apache.lucene.util.ArrayUtil; import org.apache.lucene.util.Attribute; +import org.apache.lucene.util.AttributeSource; import org.apache.lucene.util.AttributeImpl; /** @@ -879,4 +880,46 @@ public class Token extends AttributeImpl ((TypeAttribute) target).setType(type); } } + + /** Convenience factory that returns Token as implementation for the basic + * attributes and return the default impl (with "Impl" appended) for all other + * attributes. + * @since 3.0 + */ + public static final AttributeSource.AttributeFactory TOKEN_ATTRIBUTE_FACTORY = + new TokenAttributeFactory(AttributeSource.AttributeFactory.DEFAULT_ATTRIBUTE_FACTORY); + + /** Expert: Creates a TokenAttributeFactory returning {@link Token} as instance for the basic attributes + * and for all other attributes calls the given delegate factory. + * @since 3.0 + */ + public static final class TokenAttributeFactory extends AttributeSource.AttributeFactory { + + private final AttributeSource.AttributeFactory delegate; + + /** Expert: Creates an AttributeFactory returning {@link Token} as instance for the basic attributes + * and for all other attributes calls the given delegate factory. */ + public TokenAttributeFactory(AttributeSource.AttributeFactory delegate) { + this.delegate = delegate; + } + + public AttributeImpl createAttributeInstance(Class attClass) { + return attClass.isAssignableFrom(Token.class) + ? new Token() : delegate.createAttributeInstance(attClass); + } + + public boolean equals(Object other) { + if (this == other) return true; + if (other instanceof TokenAttributeFactory) { + final TokenAttributeFactory af = (TokenAttributeFactory) other; + return this.delegate.equals(af.delegate); + } + return false; + } + + public int hashCode() { + return delegate.hashCode() ^ 0x0a45aa31; + } + } + } diff --git a/src/java/org/apache/lucene/util/AttributeSource.java b/src/java/org/apache/lucene/util/AttributeSource.java index 2dd00178474..4286ec1c02e 100644 --- a/src/java/org/apache/lucene/util/AttributeSource.java +++ b/src/java/org/apache/lucene/util/AttributeSource.java @@ -172,7 +172,14 @@ public class AttributeSource { private static final IdentityHashMap,LinkedList>> knownImplClasses = new IdentityHashMap,LinkedList>>(); - /** Adds a custom AttributeImpl instance with one or more Attribute interfaces. */ + /** Expert: Adds a custom AttributeImpl instance with one or more Attribute interfaces. + *

Please note: It is not guaranteed, that att is added to + * the AttributeSource, because the provided attributes may already exist. + * You should always retrieve the wanted attributes using {@link #getAttribute} after adding + * with this method and cast to your class. + * The recommended way to use custom implementations is using an {@link AttributeFactory}. + *

+ */ public void addAttributeImpl(final AttributeImpl att) { final Class clazz = att.getClass(); if (attributeImpls.containsKey(clazz)) return;