LUCENE-4440: Refactor FilterCodec to get the delegate passed into ctor. Fix Codec's and PostingsFormat's forName lookup methods to throw IllegalStateException if you call those methods from the constructor of e.g. FilterCodec.

git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1391140 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Uwe Schindler 2012-09-27 17:47:46 +00:00
parent f0efba1a06
commit f37e5e2de6
8 changed files with 55 additions and 51 deletions

View File

@ -70,9 +70,11 @@ New Features
API Changes
* LUCENE-4391: All methods of Lucene40Codec but getPostingsFormatForField are
now final. To reuse functionality of Lucene40, you should extend FilterCodec
and delegate to Lucene40 instead of extending Lucene40Codec. (Adrien Grand)
* LUCENE-4391, LUCENE-4440: All methods of Lucene40Codec but
getPostingsFormatForField are now final. To reuse functionality
of Lucene40, you should extend FilterCodec and delegate to Lucene40
instead of extending Lucene40Codec. (Adrien Grand, Shai Erea,
Robert Muir, Uwe Schindler)
* LUCENE-4299: Added Terms.hasPositions() and Terms.hasOffsets().
Previously you had no real way to know that a term vector field

View File

@ -17,7 +17,6 @@ package org.apache.lucene.codecs.appending;
* limitations under the License.
*/
import org.apache.lucene.codecs.Codec;
import org.apache.lucene.codecs.FilterCodec;
import org.apache.lucene.codecs.PostingsFormat;
import org.apache.lucene.codecs.lucene40.Lucene40Codec;
@ -32,16 +31,11 @@ import org.apache.lucene.codecs.lucene40.Lucene40Codec;
public final class AppendingCodec extends FilterCodec {
public AppendingCodec() {
super("Appending");
super("Appending", new Lucene40Codec());
}
private final PostingsFormat postings = new AppendingPostingsFormat();
@Override
protected Codec delegate() {
return Codec.forName("Lucene40");
}
@Override
public PostingsFormat postingsFormat() {
return postings;

View File

@ -21,7 +21,6 @@ import java.io.IOException;
import java.util.Random;
import org.apache.lucene.analysis.MockAnalyzer;
import org.apache.lucene.codecs.appending.AppendingCodec;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.FieldType;
import org.apache.lucene.document.TextField;
@ -34,8 +33,8 @@ import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.MultiFields;
import org.apache.lucene.index.StoredDocument;
import org.apache.lucene.index.Terms;
import org.apache.lucene.index.TermsEnum.SeekStatus;
import org.apache.lucene.index.TermsEnum;
import org.apache.lucene.index.TermsEnum.SeekStatus;
import org.apache.lucene.index.TieredMergePolicy;
import org.apache.lucene.search.DocIdSetIterator;
import org.apache.lucene.store.Directory;
@ -45,7 +44,6 @@ import org.apache.lucene.store.MockDirectoryWrapper;
import org.apache.lucene.store.RAMDirectory;
import org.apache.lucene.util.BytesRef;
import org.apache.lucene.util.LuceneTestCase;
import org.apache.lucene.util.Version;
public class TestAppendingCodec extends LuceneTestCase {
@ -111,7 +109,7 @@ public class TestAppendingCodec extends LuceneTestCase {
public void testCodec() throws Exception {
Directory dir = new AppendingRAMDirectory(random(), new RAMDirectory());
IndexWriterConfig cfg = new IndexWriterConfig(Version.LUCENE_40, new MockAnalyzer(random()));
IndexWriterConfig cfg = new IndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random()));
cfg.setCodec(new AppendingCodec());
((TieredMergePolicy)cfg.getMergePolicy()).setUseCompoundFile(false);
@ -153,7 +151,7 @@ public class TestAppendingCodec extends LuceneTestCase {
public void testCompoundFile() throws Exception {
Directory dir = new AppendingRAMDirectory(random(), new RAMDirectory());
IndexWriterConfig cfg = new IndexWriterConfig(Version.LUCENE_40, new MockAnalyzer(random()));
IndexWriterConfig cfg = new IndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random()));
TieredMergePolicy mp = new TieredMergePolicy();
mp.setUseCompoundFile(true);
mp.setNoCFSRatio(1.0);

View File

@ -30,8 +30,10 @@ import org.apache.lucene.util.NamedSPILoader;
* written into the index. In order for the segment to be read, the
* name must resolve to your implementation via {@link #forName(String)}.
* This method uses Java's
* {@link ServiceLoader Service Provider Interface} to resolve codec names.
* {@link ServiceLoader Service Provider Interface} (SPI) to resolve codec names.
* <p>
* If you implement your own codec, make sure that it has a no-arg constructor
* so SPI can load it.
* @see ServiceLoader
*/
public abstract class Codec implements NamedSPILoader.NamedSPI {
@ -49,7 +51,7 @@ public abstract class Codec implements NamedSPILoader.NamedSPI {
* SPI mechanism (registered in META-INF/ of your jar file, etc).
* @param name must be all ascii alphanumeric, and less than 128 characters in length.
*/
public Codec(String name) {
protected Codec(String name) {
NamedSPILoader.checkServiceName(name);
this.name = name;
}
@ -86,11 +88,19 @@ public abstract class Codec implements NamedSPILoader.NamedSPI {
/** looks up a codec by name */
public static Codec forName(String name) {
if (loader == null) {
throw new IllegalStateException("You called Codec.forName() before all Codecs could be initialized. "+
"This likely happens if you call it from a Codec's ctor.");
}
return loader.lookup(name);
}
/** returns a list of all available codec names */
public static Set<String> availableCodecs() {
if (loader == null) {
throw new IllegalStateException("You called Codec.availableCodecs() before all Codecs could be initialized. "+
"This likely happens if you call it from a Codec's ctor.");
}
return loader.availableServices();
}

View File

@ -27,11 +27,7 @@ package org.apache.lucene.codecs;
* public final class CustomCodec extends FilterCodec {
*
* public CustomCodec() {
* super("CustomCodec");
* }
*
* public Codec delegate() {
* return Codec.forName("Lucene40");
* super("CustomCodec", new Lucene40Codec());
* }
*
* public LiveDocsFormat liveDocsFormat() {
@ -40,58 +36,63 @@ package org.apache.lucene.codecs;
*
* }
* </pre>
*
* <p><em>Please note:</em> Don't call {@link Codec#forName} from
* the no-arg constructor of your own codec. When the SPI framework
* loads your own Codec as SPI component, SPI has not yet fully initialized!
* If you want to extend another Codec, instantiate it directly by calling
* its constructor.
*
* @lucene.experimental
*/
public abstract class FilterCodec extends Codec {
protected final Codec delegate;
/** Sole constructor. */
public FilterCodec(String name) {
protected FilterCodec(String name, Codec delegate) {
super(name);
this.delegate = delegate;
}
/**
* Return the codec that is responsible for providing default format
* implementations.
*/
protected abstract Codec delegate();
@Override
public DocValuesFormat docValuesFormat() {
return delegate().docValuesFormat();
return delegate.docValuesFormat();
}
@Override
public FieldInfosFormat fieldInfosFormat() {
return delegate().fieldInfosFormat();
return delegate.fieldInfosFormat();
}
@Override
public LiveDocsFormat liveDocsFormat() {
return delegate().liveDocsFormat();
return delegate.liveDocsFormat();
}
@Override
public NormsFormat normsFormat() {
return delegate().normsFormat();
return delegate.normsFormat();
}
@Override
public PostingsFormat postingsFormat() {
return delegate().postingsFormat();
return delegate.postingsFormat();
}
@Override
public SegmentInfoFormat segmentInfoFormat() {
return delegate().segmentInfoFormat();
return delegate.segmentInfoFormat();
}
@Override
public StoredFieldsFormat storedFieldsFormat() {
return delegate().storedFieldsFormat();
return delegate.storedFieldsFormat();
}
@Override
public TermVectorsFormat termVectorsFormat() {
return delegate().termVectorsFormat();
return delegate.termVectorsFormat();
}
}

View File

@ -33,8 +33,10 @@ import org.apache.lucene.util.NamedSPILoader;
* written into the index in certain configurations. In order for the segment
* to be read, the name must resolve to your implementation via {@link #forName(String)}.
* This method uses Java's
* {@link ServiceLoader Service Provider Interface} to resolve codec names.
* {@link ServiceLoader Service Provider Interface} (SPI) to resolve format names.
* <p>
* If you implement your own format, make sure that it has a no-arg constructor
* so SPI can load it.
* @see ServiceLoader
* @lucene.experimental */
public abstract class PostingsFormat implements NamedSPILoader.NamedSPI {
@ -91,11 +93,19 @@ public abstract class PostingsFormat implements NamedSPILoader.NamedSPI {
/** looks up a format by name */
public static PostingsFormat forName(String name) {
if (loader == null) {
throw new IllegalStateException("You called PostingsFormat.forName() before all formats could be initialized. "+
"This likely happens if you call it from a PostingsFormat's ctor.");
}
return loader.lookup(name);
}
/** returns a list of all available format names */
public static Set<String> availablePostingsFormats() {
if (loader == null) {
throw new IllegalStateException("You called PostingsFormat.availablePostingsFormats() before all formats could be initialized. "+
"This likely happens if you call it from a PostingsFormat's ctor.");
}
return loader.availableServices();
}

View File

@ -1109,12 +1109,7 @@ public class TestAddIndexes extends LuceneTestCase {
private static final class UnRegisteredCodec extends FilterCodec {
public UnRegisteredCodec() {
super("NotRegistered");
}
@Override
protected Codec delegate() {
return Codec.forName("Lucene40");
super("NotRegistered", new Lucene40Codec());
}
}

View File

@ -17,7 +17,6 @@ package org.apache.lucene.codecs.asserting;
* limitations under the License.
*/
import org.apache.lucene.codecs.Codec;
import org.apache.lucene.codecs.FilterCodec;
import org.apache.lucene.codecs.PostingsFormat;
import org.apache.lucene.codecs.TermVectorsFormat;
@ -32,12 +31,7 @@ public final class AssertingCodec extends FilterCodec {
private final TermVectorsFormat vectors = new AssertingTermVectorsFormat();
public AssertingCodec() {
super("Asserting");
}
@Override
protected Codec delegate() {
return Codec.forName("Lucene40");
super("Asserting", new Lucene40Codec());
}
@Override