mirror of https://github.com/apache/lucene.git
SOLR-5264 - move config argument retrieval/removal from Update Processor code to NamedList
git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1528680 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
2cb0a5c0da
commit
86a0b893fe
|
@ -217,7 +217,7 @@ public class AddSchemaFieldsUpdateProcessorFactory extends UpdateRequestProcesso
|
|||
String fieldType = fieldTypeObj.toString();
|
||||
|
||||
Collection<String> valueClasses
|
||||
= FieldMutatingUpdateProcessorFactory.oneOrMany(typeMappingNamedList, VALUE_CLASS_PARAM);
|
||||
= typeMappingNamedList.removeConfigArgs(VALUE_CLASS_PARAM);
|
||||
if (valueClasses.isEmpty()) {
|
||||
throw new SolrException(SERVER_ERROR,
|
||||
"Each '" + TYPE_MAPPING_PARAM + "' <lst/> must contain at least one '" + VALUE_CLASS_PARAM + "' <str>");
|
||||
|
|
|
@ -176,7 +176,7 @@ public class CloneFieldUpdateProcessorFactory
|
|||
} else {
|
||||
// source better be one or more strings
|
||||
srcInclusions.fieldName = new HashSet<String>
|
||||
(FieldMutatingUpdateProcessorFactory.oneOrMany(args, "source"));
|
||||
(args.removeConfigArgs("source"));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -17,8 +17,8 @@
|
|||
|
||||
package org.apache.solr.update.processor;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
|
@ -27,10 +27,9 @@ import java.util.Set;
|
|||
import java.util.regex.Pattern;
|
||||
import java.util.regex.PatternSyntaxException;
|
||||
|
||||
import org.apache.solr.core.SolrCore;
|
||||
import org.apache.solr.common.SolrException;
|
||||
import static org.apache.solr.common.SolrException.ErrorCode.*;
|
||||
import org.apache.solr.common.util.NamedList;
|
||||
import org.apache.solr.core.SolrCore;
|
||||
import org.apache.solr.util.plugin.SolrCoreAware;
|
||||
|
||||
|
||||
|
@ -133,18 +132,18 @@ public abstract class FieldMutatingUpdateProcessorFactory
|
|||
protected final FieldMutatingUpdateProcessor.FieldNameSelector getSelector() {
|
||||
if (null != selector) return selector;
|
||||
|
||||
throw new SolrException(SERVER_ERROR, "selector was never initialized, "+
|
||||
" inform(SolrCore) never called???");
|
||||
throw new SolrException(SolrException.ErrorCode.SERVER_ERROR,
|
||||
"selector was never initialized, inform(SolrCore) never called???");
|
||||
}
|
||||
|
||||
public static SelectorParams parseSelectorParams(NamedList args) {
|
||||
SelectorParams params = new SelectorParams();
|
||||
|
||||
params.fieldName = new HashSet<String>(oneOrMany(args, "fieldName"));
|
||||
params.typeName = new HashSet<String>(oneOrMany(args, "typeName"));
|
||||
params.fieldName = new HashSet<String>(args.removeConfigArgs("fieldName"));
|
||||
params.typeName = new HashSet<String>(args.removeConfigArgs("typeName"));
|
||||
|
||||
// we can compile the patterns now
|
||||
Collection<String> patterns = oneOrMany(args, "fieldRegex");
|
||||
Collection<String> patterns = args.removeConfigArgs("fieldRegex");
|
||||
if (! patterns.isEmpty()) {
|
||||
params.fieldRegex = new ArrayList<Pattern>(patterns.size());
|
||||
for (String s : patterns) {
|
||||
|
@ -152,13 +151,14 @@ public abstract class FieldMutatingUpdateProcessorFactory
|
|||
params.fieldRegex.add(Pattern.compile(s));
|
||||
} catch (PatternSyntaxException e) {
|
||||
throw new SolrException
|
||||
(SERVER_ERROR, "Invalid 'fieldRegex' pattern: " + s, e);
|
||||
(SolrException.ErrorCode.SERVER_ERROR,
|
||||
"Invalid 'fieldRegex' pattern: " + s, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// resolve this into actual Class objects later
|
||||
params.typeClass = oneOrMany(args, "typeClass");
|
||||
params.typeClass = args.removeConfigArgs("typeClass");
|
||||
|
||||
// getBooleanArg() returns null if the arg is not specified
|
||||
params.fieldNameMatchesSchemaField = getBooleanArg(args, "fieldNameMatchesSchemaField");
|
||||
|
@ -171,17 +171,17 @@ public abstract class FieldMutatingUpdateProcessorFactory
|
|||
List<Object> excList = args.getAll("exclude");
|
||||
for (Object excObj : excList) {
|
||||
if (null == excObj) {
|
||||
throw new SolrException
|
||||
(SERVER_ERROR, "'exclude' init param can not be null");
|
||||
throw new SolrException (SolrException.ErrorCode.SERVER_ERROR,
|
||||
"'exclude' init param can not be null");
|
||||
}
|
||||
if (! (excObj instanceof NamedList) ) {
|
||||
throw new SolrException
|
||||
(SERVER_ERROR, "'exclude' init param must be <lst/>");
|
||||
throw new SolrException (SolrException.ErrorCode.SERVER_ERROR,
|
||||
"'exclude' init param must be <lst/>");
|
||||
}
|
||||
NamedList exc = (NamedList) excObj;
|
||||
exclusions.add(parseSelectorParams(exc));
|
||||
if (0 < exc.size()) {
|
||||
throw new SolrException(SERVER_ERROR,
|
||||
throw new SolrException(SolrException.ErrorCode.SERVER_ERROR,
|
||||
"Unexpected 'exclude' init sub-param(s): '" +
|
||||
args.getName(0) + "'");
|
||||
}
|
||||
|
@ -207,9 +207,8 @@ public abstract class FieldMutatingUpdateProcessorFactory
|
|||
exclusions = parseSelectorExclusionParams(args);
|
||||
|
||||
if (0 < args.size()) {
|
||||
throw new SolrException(SERVER_ERROR,
|
||||
"Unexpected init param(s): '" +
|
||||
args.getName(0) + "'");
|
||||
throw new SolrException(SolrException.ErrorCode.SERVER_ERROR,
|
||||
"Unexpected init param(s): '" + args.getName(0) + "'");
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -249,7 +248,10 @@ public abstract class FieldMutatingUpdateProcessorFactory
|
|||
* Strings that key referred to. Throws an error if the key didn't refer
|
||||
* to one or more strings (or arrays of strings)
|
||||
* @exception SolrException invalid arr/str structure.
|
||||
* @deprecated Replaced by {@link NamedList#removeConfigArgs(String)}. Will be
|
||||
* removed in version 5.0.
|
||||
*/
|
||||
@Deprecated
|
||||
public static Collection<String> oneOrMany(final NamedList args, final String key) {
|
||||
List<String> result = new ArrayList<String>(args.size() / 2);
|
||||
final String err = "init arg '" + key + "' must be a string "
|
||||
|
@ -268,7 +270,7 @@ public abstract class FieldMutatingUpdateProcessorFactory
|
|||
if (o instanceof Collection) {
|
||||
for (Object item : (Collection)o) {
|
||||
if (! (item instanceof String)) {
|
||||
throw new SolrException(SERVER_ERROR, err + item.getClass());
|
||||
throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, err + item.getClass());
|
||||
}
|
||||
result.add((String)item);
|
||||
}
|
||||
|
@ -276,7 +278,7 @@ public abstract class FieldMutatingUpdateProcessorFactory
|
|||
}
|
||||
|
||||
// who knows what the hell we have
|
||||
throw new SolrException(SERVER_ERROR, err + o.getClass());
|
||||
throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, err + o.getClass());
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@ -294,7 +296,8 @@ public abstract class FieldMutatingUpdateProcessorFactory
|
|||
return null;
|
||||
}
|
||||
if (values.size() > 1) {
|
||||
throw new SolrException(SERVER_ERROR, "Only one '" + key + "' is allowed");
|
||||
throw new SolrException(SolrException.ErrorCode.SERVER_ERROR,
|
||||
"Only one '" + key + "' is allowed");
|
||||
}
|
||||
Object o = args.remove(key);
|
||||
if (o instanceof Boolean) {
|
||||
|
@ -302,7 +305,8 @@ public abstract class FieldMutatingUpdateProcessorFactory
|
|||
} else if (o instanceof CharSequence) {
|
||||
bool = Boolean.parseBoolean(o.toString());
|
||||
} else {
|
||||
throw new SolrException(SERVER_ERROR, "'" + key + "' must have type 'bool' or 'str'; found " + o.getClass());
|
||||
throw new SolrException(SolrException.ErrorCode.SERVER_ERROR,
|
||||
"'" + key + "' must have type 'bool' or 'str'; found " + o.getClass());
|
||||
}
|
||||
return bool;
|
||||
}
|
||||
|
|
|
@ -112,7 +112,7 @@ public class ParseBooleanFieldUpdateProcessorFactory extends FieldMutatingUpdate
|
|||
}
|
||||
}
|
||||
|
||||
Collection<String> trueValuesParam = oneOrMany(args, TRUE_VALUES_PARAM);
|
||||
Collection<String> trueValuesParam = args.removeConfigArgs(TRUE_VALUES_PARAM);
|
||||
if ( ! trueValuesParam.isEmpty()) {
|
||||
trueValues.clear();
|
||||
for (String trueVal : trueValuesParam) {
|
||||
|
@ -120,7 +120,7 @@ public class ParseBooleanFieldUpdateProcessorFactory extends FieldMutatingUpdate
|
|||
}
|
||||
}
|
||||
|
||||
Collection<String> falseValuesParam = oneOrMany(args, FALSE_VALUES_PARAM);
|
||||
Collection<String> falseValuesParam = args.removeConfigArgs(FALSE_VALUES_PARAM);
|
||||
if ( ! falseValuesParam.isEmpty()) {
|
||||
falseValues.clear();
|
||||
for (String val : falseValuesParam) {
|
||||
|
|
|
@ -150,7 +150,7 @@ public class ParseDateFieldUpdateProcessorFactory extends FieldMutatingUpdatePro
|
|||
defaultTimeZone = DateTimeZone.forID(defaultTimeZoneParam.toString());
|
||||
}
|
||||
|
||||
Collection<String> formatsParam = oneOrMany(args, FORMATS_PARAM);
|
||||
Collection<String> formatsParam = args.removeConfigArgs(FORMATS_PARAM);
|
||||
if (null != formatsParam) {
|
||||
for (String value : formatsParam) {
|
||||
formats.put(value, DateTimeFormat.forPattern(value).withZone(defaultTimeZone).withLocale(locale));
|
||||
|
|
|
@ -173,7 +173,7 @@ public class StatelessScriptUpdateProcessorFactory extends UpdateRequestProcesso
|
|||
@Override
|
||||
public void init(NamedList args) {
|
||||
Collection<String> scripts =
|
||||
FieldMutatingUpdateProcessorFactory.oneOrMany(args, SCRIPT_ARG);
|
||||
args.removeConfigArgs(SCRIPT_ARG);
|
||||
if (scripts.isEmpty()) {
|
||||
throw new SolrException(SolrException.ErrorCode.SERVER_ERROR,
|
||||
"StatelessScriptUpdateProcessorFactory must be " +
|
||||
|
|
|
@ -19,10 +19,14 @@ package org.apache.solr.common.util;
|
|||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.solr.common.SolrException;
|
||||
|
||||
/**
|
||||
* A simple container class for modeling an ordered list of name/value pairs.
|
||||
*
|
||||
|
@ -257,7 +261,23 @@ public class NamedList<T> implements Cloneable, Serializable, Iterable<Map.Entry
|
|||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Removes all values matching the specified name
|
||||
*
|
||||
* @param name Name
|
||||
*/
|
||||
private void killAll(String name) {
|
||||
int sz = size();
|
||||
// Go through the list backwards, removing matches as found.
|
||||
for (int i = sz - 1; i >= 0; i--) {
|
||||
String n = getName(i);
|
||||
if (name==n || (name!=null && name.equals(n))) {
|
||||
remove(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively parses the NamedList structure to arrive at a specific element.
|
||||
* As you descend the NamedList tree, the last element can be any type,
|
||||
|
@ -470,6 +490,83 @@ public class NamedList<T> implements Cloneable, Serializable, Iterable<Map.Entry
|
|||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes and returns all values for the specified name. Returns null if
|
||||
* no matches found. This method will return all matching objects,
|
||||
* regardless of data type. If you are parsing Solr config options, the
|
||||
* {@link #removeConfigArgs(String)} method will probably work better.
|
||||
*
|
||||
* @param name Name
|
||||
* @return List of values
|
||||
*/
|
||||
public List<T> removeAll(String name) {
|
||||
List<T> result = new ArrayList<T>();
|
||||
result = getAll(name);
|
||||
if (result.size() > 0 ) {
|
||||
killAll(name);
|
||||
return result;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used for getting one or many arguments from NamedList objects that hold
|
||||
* configuration parameters. Finds all entries in the NamedList that match
|
||||
* the given name. If they are all strings or arrays of strings, remove them
|
||||
* from the NamedList and return the individual elements as a {@link Collection}.
|
||||
* Parameter order will be preserved if the returned collection is handled as
|
||||
* an {@link ArrayList}. Throws SolrException if any of the values associated
|
||||
* with the name are not strings or arrays of strings. If exception is
|
||||
* thrown, the NamedList is not modified. Returns an empty collection if no
|
||||
* matches found. If you need to remove and retrieve all matching items from
|
||||
* the NamedList regardless of data type, use {@link #removeAll(String)} instead.
|
||||
*
|
||||
* @param name
|
||||
* The key to look up in the NamedList.
|
||||
* @return A collection of the values found.
|
||||
* @throws SolrException
|
||||
* If values are found for the input key that are not strings or
|
||||
* arrays of strings.
|
||||
*/
|
||||
@SuppressWarnings("rawtypes")
|
||||
public Collection<String> removeConfigArgs(final String name)
|
||||
throws SolrException {
|
||||
List<T> objects = getAll(name);
|
||||
List<String> collection = new ArrayList<String>(size() / 2);
|
||||
final String err = "init arg '" + name + "' must be a string "
|
||||
+ "(ie: 'str'), or an array (ie: 'arr') containing strings; found: ";
|
||||
|
||||
for (Object o : objects) {
|
||||
if (o instanceof String) {
|
||||
collection.add((String) o);
|
||||
continue;
|
||||
}
|
||||
|
||||
// If it's an array, convert to List (which is a Collection).
|
||||
if (o instanceof Object[]) {
|
||||
o = Arrays.asList((Object[]) o);
|
||||
}
|
||||
|
||||
// If it's a Collection, collect each value.
|
||||
if (o instanceof Collection) {
|
||||
for (Object item : (Collection) o) {
|
||||
if (!(item instanceof String)) {
|
||||
throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, err + item.getClass());
|
||||
}
|
||||
collection.add((String) item);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, err + o.getClass());
|
||||
}
|
||||
|
||||
if (collection.size() > 0) {
|
||||
killAll(name);
|
||||
}
|
||||
|
||||
return collection;
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
nvPairs.clear();
|
||||
}
|
||||
|
|
|
@ -17,7 +17,11 @@
|
|||
|
||||
package org.apache.solr.common.util;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.lucene.util.LuceneTestCase;
|
||||
import org.apache.solr.common.SolrException;
|
||||
|
||||
public class NamedListTest extends LuceneTestCase {
|
||||
public void testRemove() {
|
||||
|
@ -25,9 +29,71 @@ public class NamedListTest extends LuceneTestCase {
|
|||
nl.add("key1", "value1");
|
||||
nl.add("key2", "value2");
|
||||
assertEquals(2, nl.size());
|
||||
String value = nl.remove(0);
|
||||
String value = null;
|
||||
value = nl.remove(0);
|
||||
assertEquals("value1", value);
|
||||
assertEquals(1, nl.size());
|
||||
value = nl.remove("key2");
|
||||
assertEquals("value2", value);
|
||||
assertEquals(0, nl.size());
|
||||
}
|
||||
|
||||
public void testRemoveAll() {
|
||||
NamedList<String> nl = new NamedList<String>();
|
||||
nl.add("key1", "value1-1");
|
||||
nl.add("key2", "value2-1");
|
||||
nl.add("key1", "value1-2");
|
||||
nl.add("key2", "value2-2");
|
||||
nl.add("key1", "value1-3");
|
||||
nl.add("key2", "value2-3");
|
||||
nl.add("key1", "value1-4");
|
||||
nl.add("key2", "value2-4");
|
||||
nl.add("key1", "value1-5");
|
||||
nl.add("key2", "value2-5");
|
||||
nl.add("key1", "value1-6");
|
||||
assertEquals(11, nl.size());
|
||||
List<String> values = null;
|
||||
values = nl.removeAll("key1");
|
||||
assertEquals("value1-1", values.get(0));
|
||||
assertEquals("value1-3", values.get(2));
|
||||
assertEquals(6, values.size());
|
||||
assertEquals(5, nl.size());
|
||||
values = nl.removeAll("key2");
|
||||
assertEquals(5, values.size());
|
||||
assertEquals(0, nl.size());
|
||||
}
|
||||
|
||||
public void testRemoveArgs() {
|
||||
NamedList<Object> nl = new NamedList<Object>();
|
||||
nl.add("key1", "value1-1");
|
||||
nl.add("key2", "value2-1");
|
||||
nl.add("key1", "value1-2");
|
||||
nl.add("key2", "value2-2");
|
||||
nl.add("key1", "value1-3");
|
||||
nl.add("key2", "value2-3");
|
||||
nl.add("key1", "value1-4");
|
||||
nl.add("key2", "value2-4");
|
||||
nl.add("key1", "value1-5");
|
||||
nl.add("key2", "value2-5");
|
||||
nl.add("key1", "value1-6");
|
||||
nl.add("key2", 0);
|
||||
nl.add("key2", "value2-7");
|
||||
assertEquals(13, nl.size());
|
||||
List<String> values = (ArrayList<String>) nl.removeConfigArgs("key1");
|
||||
assertEquals("value1-1", values.get(0));
|
||||
assertEquals("value1-3", values.get(2));
|
||||
assertEquals(6, values.size());
|
||||
assertEquals(7, nl.size());
|
||||
try {
|
||||
values = (ArrayList<String>) nl.removeConfigArgs("key2");
|
||||
fail();
|
||||
}
|
||||
catch(SolrException e) {
|
||||
// Expected exception.
|
||||
assertTrue(true);
|
||||
}
|
||||
// nl should be unmodified when removeArgs throws an exception.
|
||||
assertEquals(7, nl.size());
|
||||
}
|
||||
|
||||
public void testRecursive() {
|
||||
|
|
Loading…
Reference in New Issue