SOLR-1942: Ability to specify codec per field

git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1127313 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Robert Muir 2011-05-24 21:55:28 +00:00
parent 9b31ee389f
commit 530b894c60
18 changed files with 519 additions and 7 deletions

View File

@ -88,6 +88,15 @@ public class CodecProvider {
return codec; return codec;
} }
/**
* Returns <code>true</code> iff a codec with the given name is registered
* @param name codec name
* @return <code>true</code> iff a codec with the given name is registered, otherwise <code>false</code>.
*/
public synchronized boolean isCodecRegistered(String name) {
return codecs.containsKey(name);
}
public SegmentInfosWriter getSegmentInfosWriter() { public SegmentInfosWriter getSegmentInfosWriter() {
return infosWriter; return infosWriter;
} }
@ -145,6 +154,14 @@ public class CodecProvider {
return codec; return codec;
} }
/**
* Returns <code>true</code> if this provider has a Codec registered for this
* field.
*/
public synchronized boolean hasFieldCodec(String name) {
return perFieldMap.containsKey(name);
}
/** /**
* Returns the default {@link Codec} for this {@link CodecProvider} * Returns the default {@link Codec} for this {@link CodecProvider}
* *

View File

@ -1382,6 +1382,11 @@ public abstract class LuceneTestCase extends Assert {
return codec.name; return codec.name;
} }
@Override
public synchronized boolean hasFieldCodec(String name) {
return true; // we have a codec for every field
}
@Override @Override
public synchronized String toString() { public synchronized String toString() {
return "RandomCodecProvider: " + previousMappings.toString(); return "RandomCodecProvider: " + previousMappings.toString();

View File

@ -144,6 +144,11 @@ New Features
fq={!join from=name to=parent}eyes:blue fq={!join from=name to=parent}eyes:blue
(yonik) (yonik)
* SOLR-1942: Added the ability to select codec per fieldType in schema.xml
as well as support custom CodecProviders in solrconfig.xml.
NOTE: IndexReaderFactory now has a codecProvider that should be passed
to IndexReader.open (in the case you have a custom IndexReaderFactory).
(simonw via rmuir)
Optimizations Optimizations

View File

@ -0,0 +1,32 @@
package org.apache.solr.core;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import org.apache.lucene.index.codecs.CodecProvider;
import org.apache.solr.common.util.NamedList;
import org.apache.solr.util.plugin.NamedListInitializedPlugin;
/**
* Factory for plugging in a custom {@link CodecProvider}
*/
public abstract class CodecProviderFactory implements NamedListInitializedPlugin {
public void init(NamedList args) {
}
public abstract CodecProvider create();
}

View File

@ -19,6 +19,7 @@ package org.apache.solr.core;
import java.io.IOException; import java.io.IOException;
import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.codecs.CodecProvider;
import org.apache.lucene.store.Directory; import org.apache.lucene.store.Directory;
import org.apache.solr.common.util.NamedList; import org.apache.solr.common.util.NamedList;
import org.apache.solr.util.plugin.NamedListInitializedPlugin; import org.apache.solr.util.plugin.NamedListInitializedPlugin;
@ -28,6 +29,7 @@ import org.apache.solr.util.plugin.NamedListInitializedPlugin;
*/ */
public abstract class IndexReaderFactory implements NamedListInitializedPlugin { public abstract class IndexReaderFactory implements NamedListInitializedPlugin {
protected int termInfosIndexDivisor = 1;//IndexReader.DEFAULT_TERMS_INDEX_DIVISOR; Set this once Lucene makes this public. protected int termInfosIndexDivisor = 1;//IndexReader.DEFAULT_TERMS_INDEX_DIVISOR; Set this once Lucene makes this public.
protected CodecProvider provider;
/** /**
* Potentially initializes {@link #termInfosIndexDivisor}. Overriding classes should call super.init() in order * Potentially initializes {@link #termInfosIndexDivisor}. Overriding classes should call super.init() in order
* to make sure termInfosIndexDivisor is set. * to make sure termInfosIndexDivisor is set.
@ -63,4 +65,11 @@ public abstract class IndexReaderFactory implements NamedListInitializedPlugin {
*/ */
public abstract IndexReader newReader(Directory indexDir, boolean readOnly) public abstract IndexReader newReader(Directory indexDir, boolean readOnly)
throws IOException; throws IOException;
/**
* Sets the codec provider for this IndexReaderFactory
*/
public void setCodecProvider(CodecProvider provider) {
this.provider = provider;
}
} }

View File

@ -0,0 +1,155 @@
package org.apache.solr.core;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.util.Collection;
import java.util.Set;
import org.apache.lucene.index.codecs.Codec;
import org.apache.lucene.index.codecs.CodecProvider;
import org.apache.lucene.index.codecs.SegmentInfosReader;
import org.apache.lucene.index.codecs.SegmentInfosWriter;
import org.apache.solr.schema.IndexSchema;
import org.apache.solr.schema.SchemaField;
/**
* Selects a codec based on a {@link IndexSchema}. This {@link CodecProvider}
* also supports dynamic fields such that not all field codecs need to be known
* in advance
*/
final class SchemaCodecProvider extends CodecProvider {
private final IndexSchema schema;
private final CodecProvider delegate;
SchemaCodecProvider(IndexSchema schema, CodecProvider delegate) {
this.schema = schema;
this.delegate = delegate;
}
@Override
public Codec lookup(String name) {
synchronized (delegate) {
return delegate.lookup(name);
}
}
@Override
public String getFieldCodec(String name) {
synchronized (delegate) {
if (!delegate.hasFieldCodec(name)) {
final SchemaField fieldOrNull = schema.getFieldOrNull(name);
if (fieldOrNull == null) {
throw new IllegalArgumentException("no such field " + name);
}
String codecName = fieldOrNull.getType().getCodec();
if (codecName == null) {
codecName = delegate.getDefaultFieldCodec();
}
delegate.setFieldCodec(name, codecName);
return codecName;
}
return delegate.getFieldCodec(name);
}
}
@Override
public int hashCode() {
return delegate.hashCode();
}
@Override
public void register(Codec codec) {
throw new UnsupportedOperationException();
}
@Override
public void unregister(Codec codec) {
throw new UnsupportedOperationException();
}
@Override
public Collection<String> getAllExtensions() {
return delegate.getAllExtensions();
}
@Override
public SegmentInfosWriter getSegmentInfosWriter() {
return delegate.getSegmentInfosWriter();
}
@Override
public SegmentInfosReader getSegmentInfosReader() {
return delegate.getSegmentInfosReader();
}
@Override
public boolean equals(Object obj) {
return delegate.equals(obj);
}
@Override
public void setFieldCodec(String field, String codec) {
throw new UnsupportedOperationException();
}
@Override
public String getDefaultFieldCodec() {
return delegate.getDefaultFieldCodec();
}
@Override
public boolean isCodecRegistered(String name) {
synchronized (delegate) {
return delegate.isCodecRegistered(name);
}
}
@Override
public void setDefaultFieldCodec(String codec) {
throw new UnsupportedOperationException();
}
@Override
public boolean hasFieldCodec(String fieldName) {
synchronized (delegate) {
if (!delegate.hasFieldCodec(fieldName)) {
final SchemaField fieldOrNull = schema.getFieldOrNull(fieldName);
if (fieldOrNull == null) {
return false;
}
String codecName = fieldOrNull.getType().getCodec();
if (codecName == null) {
codecName = delegate.getDefaultFieldCodec();
}
delegate.setFieldCodec(fieldName, codecName);
}
return true;
}
}
@Override
public String toString() {
return "SchemaCodecProvider(" + delegate.toString() + ")";
}
@Override
public Set<String> listAll() {
synchronized (delegate) {
return delegate.listAll();
}
}
}

View File

@ -39,6 +39,8 @@ import org.apache.solr.spelling.QueryConverter;
import org.apache.solr.highlight.SolrHighlighter; import org.apache.solr.highlight.SolrHighlighter;
import org.apache.lucene.search.BooleanQuery; import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.index.IndexDeletionPolicy; import org.apache.lucene.index.IndexDeletionPolicy;
import org.apache.lucene.index.codecs.Codec;
import org.apache.lucene.index.codecs.CodecProvider;
import org.apache.lucene.util.Version; import org.apache.lucene.util.Version;
import org.slf4j.Logger; import org.slf4j.Logger;
@ -202,6 +204,7 @@ public class SolrConfig extends Config {
loadPluginInfo(DirectoryFactory.class,"directoryFactory",false, true); loadPluginInfo(DirectoryFactory.class,"directoryFactory",false, true);
loadPluginInfo(IndexDeletionPolicy.class,"mainIndex/deletionPolicy",false, true); loadPluginInfo(IndexDeletionPolicy.class,"mainIndex/deletionPolicy",false, true);
loadPluginInfo(CodecProviderFactory.class,"mainIndex/codecProviderFactory",false, false);
loadPluginInfo(IndexReaderFactory.class,"indexReaderFactory",false, true); loadPluginInfo(IndexReaderFactory.class,"indexReaderFactory",false, true);
loadPluginInfo(UpdateRequestProcessorChain.class,"updateRequestProcessorChain",false, false); loadPluginInfo(UpdateRequestProcessorChain.class,"updateRequestProcessorChain",false, false);

View File

@ -20,6 +20,8 @@ package org.apache.solr.core;
import org.apache.lucene.index.IndexDeletionPolicy; import org.apache.lucene.index.IndexDeletionPolicy;
import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter; import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.codecs.Codec;
import org.apache.lucene.index.codecs.CodecProvider;
import org.apache.lucene.search.BooleanQuery; import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.store.Directory; import org.apache.lucene.store.Directory;
import org.apache.solr.common.SolrException; import org.apache.solr.common.SolrException;
@ -93,6 +95,7 @@ public final class SolrCore implements SolrInfoMBean {
private IndexDeletionPolicyWrapper solrDelPolicy; private IndexDeletionPolicyWrapper solrDelPolicy;
private DirectoryFactory directoryFactory; private DirectoryFactory directoryFactory;
private IndexReaderFactory indexReaderFactory; private IndexReaderFactory indexReaderFactory;
private final CodecProvider codecProvider;
public long getStartTime() { return startTime; } public long getStartTime() { return startTime; }
@ -330,6 +333,7 @@ public final class SolrCore implements SolrInfoMBean {
indexReaderFactory = new StandardIndexReaderFactory(); indexReaderFactory = new StandardIndexReaderFactory();
} }
this.indexReaderFactory = indexReaderFactory; this.indexReaderFactory = indexReaderFactory;
this.indexReaderFactory.setCodecProvider(codecProvider);
} }
// protect via synchronized(SolrCore.class) // protect via synchronized(SolrCore.class)
@ -366,7 +370,7 @@ public final class SolrCore implements SolrInfoMBean {
log.warn(logid+"Solr index directory '" + new File(indexDir) + "' doesn't exist." log.warn(logid+"Solr index directory '" + new File(indexDir) + "' doesn't exist."
+ " Creating new index..."); + " Creating new index...");
SolrIndexWriter writer = new SolrIndexWriter("SolrCore.initIndex", indexDir, getDirectoryFactory(), true, schema, solrConfig.mainIndexConfig, solrDelPolicy); SolrIndexWriter writer = new SolrIndexWriter("SolrCore.initIndex", indexDir, getDirectoryFactory(), true, schema, solrConfig.mainIndexConfig, solrDelPolicy, codecProvider);
writer.close(); writer.close();
} }
@ -493,6 +497,7 @@ public final class SolrCore implements SolrInfoMBean {
initDeletionPolicy(); initDeletionPolicy();
this.codecProvider = initCodecProvider(solrConfig, schema);
initIndex(); initIndex();
initWriters(); initWriters();
@ -555,6 +560,19 @@ public final class SolrCore implements SolrInfoMBean {
resourceLoader.inform(infoRegistry); resourceLoader.inform(infoRegistry);
} }
private CodecProvider initCodecProvider(SolrConfig solrConfig, IndexSchema schema) {
final PluginInfo info = solrConfig.getPluginInfo(CodecProviderFactory.class.getName());
CodecProvider cp;
if (info != null) {
CodecProviderFactory factory = (CodecProviderFactory) schema.getResourceLoader().newInstance(info.className);
factory.init(info.initArgs);
cp = factory.create();
} else {
// make sure we use the default if nothing is configured
cp = CodecProvider.getDefault();
}
return new SchemaCodecProvider(schema, cp);
}
/** /**
* Load the request processors * Load the request processors
@ -1618,6 +1636,10 @@ public final class SolrCore implements SolrInfoMBean {
} }
return lst; return lst;
} }
public CodecProvider getCodecProvider() {
return codecProvider;
}
} }

View File

@ -35,6 +35,6 @@ public class StandardIndexReaderFactory extends IndexReaderFactory {
@Override @Override
public IndexReader newReader(Directory indexDir, boolean readOnly) public IndexReader newReader(Directory indexDir, boolean readOnly)
throws IOException { throws IOException {
return IndexReader.open(indexDir, null, readOnly, termInfosIndexDivisor); return IndexReader.open(indexDir, null, readOnly, termInfosIndexDivisor, provider);
} }
} }

View File

@ -167,6 +167,12 @@ public abstract class FieldType extends FieldProperties {
initArgs.remove("positionIncrementGap"); initArgs.remove("positionIncrementGap");
} }
final String codec = initArgs.get("codec");
if (codec != null) {
this.codec = codec;
initArgs.remove("codec");
}
if (initArgs.size() > 0) { if (initArgs.size() > 0) {
throw new RuntimeException("schema fieldtype " + typeName throw new RuntimeException("schema fieldtype " + typeName
+ "("+ this.getClass().getName() + ")" + "("+ this.getClass().getName() + ")"
@ -537,6 +543,15 @@ public abstract class FieldType extends FieldProperties {
this.similarity = similarity; this.similarity = similarity;
} }
/**
* The codec ID used for this field type
*/
protected String codec;
public String getCodec() {
return codec;
}
/** /**
* calls back to TextResponseWriter to write the field value * calls back to TextResponseWriter to write the field value
*/ */

View File

@ -18,7 +18,10 @@
package org.apache.solr.update; package org.apache.solr.update;
import org.apache.lucene.index.*; import org.apache.lucene.index.*;
import org.apache.lucene.index.IndexWriterConfig.OpenMode;
import org.apache.lucene.index.codecs.CodecProvider;
import org.apache.lucene.store.*; import org.apache.lucene.store.*;
import org.apache.lucene.util.Version;
import org.apache.solr.common.SolrException; import org.apache.solr.common.SolrException;
import org.apache.solr.core.DirectoryFactory; import org.apache.solr.core.DirectoryFactory;
import org.apache.solr.schema.IndexSchema; import org.apache.solr.schema.IndexSchema;
@ -27,6 +30,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import java.io.File; import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStream; import java.io.OutputStream;
@ -79,16 +83,21 @@ public class SolrIndexWriter extends IndexWriter {
return d; return d;
} }
public SolrIndexWriter(String name, String path, DirectoryFactory dirFactory, boolean create, IndexSchema schema, SolrIndexConfig config, IndexDeletionPolicy delPolicy) throws IOException { public SolrIndexWriter(String name, String path, DirectoryFactory dirFactory, boolean create, IndexSchema schema, SolrIndexConfig config, IndexDeletionPolicy delPolicy, CodecProvider codecProvider) throws IOException {
super( super(
getDirectory(path, dirFactory, config), getDirectory(path, dirFactory, config),
config.toIndexWriterConfig(schema). config.toIndexWriterConfig(schema).
setOpenMode(create ? IndexWriterConfig.OpenMode.CREATE : IndexWriterConfig.OpenMode.APPEND). setOpenMode(create ? IndexWriterConfig.OpenMode.CREATE : IndexWriterConfig.OpenMode.APPEND).
setIndexDeletionPolicy(delPolicy) setIndexDeletionPolicy(delPolicy).setCodecProvider(codecProvider)
); );
log.debug("Opened Writer " + name); log.debug("Opened Writer " + name);
this.name = name; this.name = name;
setInfoStream(config);
}
private void setInfoStream(SolrIndexConfig config)
throws IOException {
String infoStreamFile = config.infoStreamFile; String infoStreamFile = config.infoStreamFile;
if (infoStreamFile != null) { if (infoStreamFile != null) {
File f = new File(infoStreamFile); File f = new File(infoStreamFile);

View File

@ -98,7 +98,7 @@ public abstract class UpdateHandler implements SolrInfoMBean {
} }
protected SolrIndexWriter createMainIndexWriter(String name, boolean removeAllExisting) throws IOException { protected SolrIndexWriter createMainIndexWriter(String name, boolean removeAllExisting) throws IOException {
return new SolrIndexWriter(name,core.getNewIndexDir(), core.getDirectoryFactory(), removeAllExisting, schema, core.getSolrConfig().mainIndexConfig, core.getDeletionPolicy()); return new SolrIndexWriter(name,core.getNewIndexDir(), core.getDirectoryFactory(), removeAllExisting, schema, core.getSolrConfig().mainIndexConfig, core.getDeletionPolicy(), core.getCodecProvider());
} }
protected final Term idTerm(String readableId) { protected final Term idTerm(String readableId) {

View File

@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<schema name="codec" version="1.2">
<types>
<fieldType name="string_pulsing" class="solr.StrField" codec="Pulsing"/>
<fieldType name="string_simpletext" class="solr.StrField" codec="SimpleText"/>
<fieldType name="string_standard" class="solr.StrField" codec="Standard"/>
<fieldType name="string" class="solr.StrField" />
</types>
<fields>
<field name="string_pulsing_f" type="string_pulsing" indexed="true" stored="true" />
<field name="string_simpletext_f" type="string_simpletext" indexed="true" stored="true" />
<field name="string_standard_f" type="string_standard" indexed="true" stored="true" />
<field name="string_f" type="string" indexed="true" stored="true" />
<dynamicField name="*_simple" type="string_simpletext" indexed="true" stored="true"/>
<dynamicField name="*_pulsing" type="string_pulsing" indexed="true" stored="true"/>
<dynamicField name="*_standard" type="string_standard" indexed="true" stored="true"/>
</fields>
<defaultSearchField>string_f</defaultSearchField>
<uniqueKey>string_f</uniqueKey>
</schema>

View File

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<config>
<luceneMatchVersion>${tests.luceneMatchVersion:LUCENE_CURRENT}</luceneMatchVersion>
<mainIndex>
<codecProviderFactory class="org.apache.solr.core.MockCodecProviderFactory">
<str name="defaultCodec">Pulsing</str>
<lst name="codecs">
<str name="codec">org.apache.lucene.index.codecs.simpletext.SimpleTextCodec</str>
<str name="codec">org.apache.lucene.index.codecs.preflex.PreFlexCodec</str>
</lst>
</codecProviderFactory>
</mainIndex>
<requestHandler name="standard" class="solr.StandardRequestHandler"></requestHandler>
</config>

View File

@ -120,7 +120,7 @@ public class BasicFunctionalityTest extends SolrTestCaseJ4 {
// test merge factor picked up // test merge factor picked up
SolrCore core = h.getCore(); SolrCore core = h.getCore();
SolrIndexWriter writer = new SolrIndexWriter("testWriter",core.getNewIndexDir(), core.getDirectoryFactory(), false, core.getSchema(), core.getSolrConfig().mainIndexConfig, core.getDeletionPolicy()); SolrIndexWriter writer = new SolrIndexWriter("testWriter",core.getNewIndexDir(), core.getDirectoryFactory(), false, core.getSchema(), core.getSolrConfig().mainIndexConfig, core.getDeletionPolicy(), core.getCodecProvider());
assertEquals("Mergefactor was not picked up", ((LogMergePolicy) writer.getConfig().getMergePolicy()).getMergeFactor(), 8); assertEquals("Mergefactor was not picked up", ((LogMergePolicy) writer.getConfig().getMergePolicy()).getMergeFactor(), 8);
writer.close(); writer.close();

View File

@ -47,7 +47,7 @@ public class BasicZkTest extends AbstractZkTestCase {
SolrCore core = h.getCore(); SolrCore core = h.getCore();
SolrIndexWriter writer = new SolrIndexWriter("testWriter", core SolrIndexWriter writer = new SolrIndexWriter("testWriter", core
.getNewIndexDir(), core.getDirectoryFactory(), false, core.getSchema(), .getNewIndexDir(), core.getDirectoryFactory(), false, core.getSchema(),
core.getSolrConfig().mainIndexConfig, core.getDeletionPolicy()); core.getSolrConfig().mainIndexConfig, core.getDeletionPolicy(), core.getCodecProvider());
assertEquals("Mergefactor was not picked up", ((LogMergePolicy)writer.getConfig().getMergePolicy()).getMergeFactor(), 8); assertEquals("Mergefactor was not picked up", ((LogMergePolicy)writer.getConfig().getMergePolicy()).getMergeFactor(), 8);
writer.close(); writer.close();

View File

@ -0,0 +1,63 @@
package org.apache.solr.core;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import org.apache.lucene.index.codecs.Codec;
import org.apache.lucene.index.codecs.CodecProvider;
import org.apache.lucene.index.codecs.pulsing.PulsingCodec;
import org.apache.lucene.index.codecs.standard.StandardCodec;
import org.apache.solr.common.util.NamedList;
/**
* CodecProviderFactory for testing, it inits a CP with Standard and Pulsing,
* and also adds any codecs specified by classname in solrconfig.
*/
public class MockCodecProviderFactory extends CodecProviderFactory {
private String defaultCodec;
private NamedList codecs;
@Override
public void init(NamedList args) {
super.init(args);
defaultCodec = (String) args.get("defaultCodec");
codecs = (NamedList) args.get("codecs");
}
@Override
public CodecProvider create() {
CodecProvider cp = new CodecProvider();
cp.register(new StandardCodec());
cp.register(new PulsingCodec(1));
if (codecs != null) {
for (Object codec : codecs.getAll("name")) {
if (!cp.isCodecRegistered((String)codec)) {
try {
Class<? extends Codec> clazz = Class.forName((String)codec).asSubclass(Codec.class);
cp.register(clazz.newInstance());
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
}
if (defaultCodec != null) {
cp.setDefaultFieldCodec(defaultCodec);
}
return cp;
}
}

View File

@ -0,0 +1,106 @@
package org.apache.solr.core;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.util.Map;
import org.apache.lucene.index.codecs.CodecProvider;
import org.apache.lucene.index.codecs.standard.StandardCodec;
import org.apache.solr.SolrTestCaseJ4;
import org.apache.solr.schema.SchemaField;
import org.junit.BeforeClass;
public class TestCodecProviderSupport extends SolrTestCaseJ4 {
@BeforeClass
public static void beforeClass() throws Exception {
initCore("solrconfig_codec.xml", "schema_codec.xml");
}
public void testCodecs() {
CodecProvider codecProvider = h.getCore().getCodecProvider();
Map<String, SchemaField> fields = h.getCore().getSchema().getFields();
SchemaField schemaField = fields.get("string_pulsing_f");
assertEquals("Pulsing", codecProvider.getFieldCodec(schemaField.getName()));
schemaField = fields.get("string_simpletext_f");
assertEquals("SimpleText",
codecProvider.getFieldCodec(schemaField.getName()));
schemaField = fields.get("string_standard_f");
assertEquals("Standard", codecProvider.getFieldCodec(schemaField.getName()));
schemaField = fields.get("string_f");
assertEquals("Pulsing", codecProvider.getFieldCodec(schemaField.getName()));
assertTrue(codecProvider.hasFieldCodec("string_simpletext_f"));
assertTrue(codecProvider.hasFieldCodec("string_standard_f"));
assertTrue(codecProvider.hasFieldCodec("string_f"));
}
public void testDynamicFields() {
CodecProvider codecProvider = h.getCore().getCodecProvider();
assertTrue(codecProvider.hasFieldCodec("bar_simple"));
assertTrue(codecProvider.hasFieldCodec("bar_pulsing"));
assertTrue(codecProvider.hasFieldCodec("bar_standard"));
assertEquals("SimpleText", codecProvider.getFieldCodec("foo_simple"));
assertEquals("Pulsing", codecProvider.getFieldCodec("foo_pulsing"));
assertEquals("Standard", codecProvider.getFieldCodec("foo_standard"));
}
public void testUnmodifiable() {
CodecProvider codecProvider = h.getCore().getCodecProvider();
try {
codecProvider.setDefaultFieldCodec("foo");
fail("should be unmodifiable");
} catch (UnsupportedOperationException e) {
//
}
try {
codecProvider.setFieldCodec("foo", "bar");
fail("should be unmodifiable");
} catch (UnsupportedOperationException e) {
//
}
try {
codecProvider.register(new StandardCodec());
fail("should be unmodifiable");
} catch (UnsupportedOperationException e) {
//
}
try {
codecProvider.unregister(new StandardCodec());
fail("should be unmodifiable");
} catch (UnsupportedOperationException e) {
//
}
}
public void testUnknownField() {
CodecProvider codecProvider = h.getCore().getCodecProvider();
try {
codecProvider.getFieldCodec("notexisting");
fail("field is not existing");
} catch (IllegalArgumentException e) {
//
}
}
}