Index: lucene/codecs/src/java/org/apache/lucene/codecs/appending/AppendingCodec.java =================================================================== --- lucene/codecs/src/java/org/apache/lucene/codecs/appending/AppendingCodec.java (revision 1391096) +++ lucene/codecs/src/java/org/apache/lucene/codecs/appending/AppendingCodec.java (working copy) @@ -17,7 +17,6 @@ * 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,17 +31,12 @@ 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; } Index: lucene/codecs/src/test/org/apache/lucene/codecs/appending/TestAppendingCodec.java =================================================================== --- lucene/codecs/src/test/org/apache/lucene/codecs/appending/TestAppendingCodec.java (revision 1391096) +++ lucene/codecs/src/test/org/apache/lucene/codecs/appending/TestAppendingCodec.java (working copy) @@ -21,7 +21,6 @@ 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.MultiFields; import org.apache.lucene.index.StoredDocument; import org.apache.lucene.index.Terms; +import org.apache.lucene.index.TermsEnum; import org.apache.lucene.index.TermsEnum.SeekStatus; -import org.apache.lucene.index.TermsEnum; 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.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 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 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); Index: lucene/core/src/java/org/apache/lucene/codecs/Codec.java =================================================================== --- lucene/core/src/java/org/apache/lucene/codecs/Codec.java (revision 1391096) +++ lucene/core/src/java/org/apache/lucene/codecs/Codec.java (working copy) @@ -30,8 +30,10 @@ * 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. *
+ * 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 @@
* 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 @@
/** 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 happens likely if you call it from a Codec's ctor.");
+ }
return loader.lookup(name);
}
/** returns a list of all available codec names */
public static Set Please note: 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();
}
}
Index: lucene/core/src/java/org/apache/lucene/codecs/PostingsFormat.java
===================================================================
--- lucene/core/src/java/org/apache/lucene/codecs/PostingsFormat.java (revision 1391096)
+++ lucene/core/src/java/org/apache/lucene/codecs/PostingsFormat.java (working copy)
@@ -33,8 +33,10 @@
* 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.
*
+ * 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 @@
/** 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 happens likely if you call it from a Codec's ctor.");
+ }
return loader.lookup(name);
}
/** returns a list of all available format names */
public static Set