Skip to content

Commit

Permalink
Move DOMUtil ConfigNode methods to ConfigNode, with some name changes.
Browse files Browse the repository at this point in the history
ConfigNode.requiredStrAttr -> attrRequired
ConfigNode.child (ex) -> childRequired
ConfigNode.getAll move name to first param; don't use empty set

PluginInfo: don't need the XML Node constructor anymore
  • Loading branch information
dsmiley committed Jan 12, 2025
1 parent 4aae151 commit d27b171
Show file tree
Hide file tree
Showing 13 changed files with 133 additions and 181 deletions.
48 changes: 9 additions & 39 deletions solr/core/src/java/org/apache/solr/core/PluginInfo.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import static org.apache.solr.common.params.CoreAdminParams.NAME;
import static org.apache.solr.schema.FieldType.CLASS_NAME;

import com.google.common.annotations.VisibleForTesting;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
Expand All @@ -30,10 +31,9 @@
import java.util.Map;
import org.apache.solr.common.ConfigNode;
import org.apache.solr.common.MapSerializable;
import org.apache.solr.common.util.DOMUtil;
import org.apache.solr.common.util.NamedList;
import org.apache.solr.util.DOMConfigNode;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

/** An Object which represents a Plugin of any type */
public class PluginInfo implements MapSerializable {
Expand Down Expand Up @@ -100,39 +100,23 @@ public String toString() {
}
}

/** From XML. */
public PluginInfo(ConfigNode node, String err, boolean requireName, boolean requireClass) {
type = node.name();
name =
node.requiredStrAttr(
NAME,
requireName
? () -> new RuntimeException(err + ": missing mandatory attribute 'name'")
: null);
name = requireName ? node.attrRequired(NAME, err) : node.attr(NAME);
cName =
parseClassName(
node.requiredStrAttr(
CLASS_NAME,
requireClass
? () -> new RuntimeException(err + ": missing mandatory attribute 'class'")
: null));
parseClassName(requireClass ? node.attrRequired(CLASS_NAME, err) : node.attr(CLASS_NAME));
className = cName.className;
pkgName = cName.pkg;
initArgs = DOMUtil.childNodesToNamedList(node);
initArgs = node.childNodesToNamedList();
attributes = node.attributes();
children = loadSubPlugins(node);
isFromSolrConfig = true;
}

public PluginInfo(Node node, String err, boolean requireName, boolean requireClass) {
type = node.getNodeName();
name = DOMUtil.getAttr(node, NAME, requireName ? err : null);
cName = parseClassName(DOMUtil.getAttr(node, CLASS_NAME, requireClass ? err : null));
className = cName.className;
pkgName = cName.pkg;
initArgs = DOMUtil.childNodesToNamedList(node);
attributes = unmodifiableMap(DOMUtil.toMap(node.getAttributes()));
children = loadSubPlugins(node);
isFromSolrConfig = true;
@VisibleForTesting
PluginInfo(Node node, String err, boolean requireName, boolean requireClass) {
this(new DOMConfigNode(node), err, requireName, requireClass);
}

@SuppressWarnings({"unchecked", "rawtypes"})
Expand Down Expand Up @@ -181,20 +165,6 @@ private List<PluginInfo> loadSubPlugins(ConfigNode node) {
return children.isEmpty() ? Collections.emptyList() : unmodifiableList(children);
}

private List<PluginInfo> loadSubPlugins(Node node) {
List<PluginInfo> children = new ArrayList<>();
// if there is another sub tag with a non namedlist tag that has to be another plugin
NodeList nlst = node.getChildNodes();
for (int i = 0; i < nlst.getLength(); i++) {
Node nd = nlst.item(i);
if (nd.getNodeType() != Node.ELEMENT_NODE) continue;
if (NL_TAGS.contains(nd.getNodeName())) continue;
PluginInfo pluginInfo = new PluginInfo(nd, null, false, false);
if (pluginInfo.isEnabled()) children.add(pluginInfo);
}
return children.isEmpty() ? Collections.emptyList() : unmodifiableList(children);
}

@Override
public String toString() {
StringBuilder sb = new StringBuilder("{");
Expand Down
4 changes: 2 additions & 2 deletions solr/core/src/java/org/apache/solr/core/SolrConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ private SolrConfig(SolrResourceLoader loader, String name, Properties substituta
getRequestParams();
initLibs(loader);
String val =
root.child(
root.childRequired(
IndexSchema.LUCENE_MATCH_VERSION_PARAM,
() -> new RuntimeException("Missing: " + IndexSchema.LUCENE_MATCH_VERSION_PARAM))
.txt();
Expand Down Expand Up @@ -517,7 +517,7 @@ public static class SolrPluginInfo {
final Function<SolrConfig, List<ConfigNode>> configReader;

private SolrPluginInfo(Class<?> clz, String tag, PluginOpts... opts) {
this(solrConfig -> solrConfig.root.getAll(null, tag), clz, tag, opts);
this(solrConfig -> solrConfig.root.getAll(tag), clz, tag, opts);
}

private SolrPluginInfo(
Expand Down
6 changes: 3 additions & 3 deletions solr/core/src/java/org/apache/solr/core/SolrXmlConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,7 @@ private static Properties loadProperties(ConfigNode cfg, Properties substitutePr
}

private static NamedList<Object> readNodeListAsNamedList(ConfigNode cfg, String section) {
NamedList<Object> nl = DOMUtil.readNamedListChildren(cfg);
NamedList<Object> nl = cfg.childNodesToNamedList();
Set<String> keys = new HashSet<>();
for (Map.Entry<String, Object> entry : nl) {
if (!keys.add(entry.getKey()))
Expand Down Expand Up @@ -724,7 +724,7 @@ private static MetricsConfig getMetricsConfig(ConfigNode metrics) {
builder.setHistogramSupplier(getPluginInfo(metrics.get("suppliers").get("histogram")));

if (metrics.get("missingValues").exists()) {
NamedList<Object> missingValues = DOMUtil.childNodesToNamedList(metrics.get("missingValues"));
NamedList<Object> missingValues = metrics.get("missingValues").childNodesToNamedList();
builder.setNullNumber(decodeNullValue(missingValues.get("nullNumber")));
builder.setNotANumber(decodeNullValue(missingValues.get("notANumber")));
builder.setNullString(decodeNullValue(missingValues.get("nullString")));
Expand All @@ -734,7 +734,7 @@ private static MetricsConfig getMetricsConfig(ConfigNode metrics) {
ConfigNode caching = metrics.get("solr/metrics/caching");
if (caching != null) {
Object threadsCachingIntervalSeconds =
DOMUtil.childNodesToNamedList(caching).get("threadsIntervalSeconds");
caching.childNodesToNamedList().get("threadsIntervalSeconds");
builder.setCacheConfig(
new MetricsConfig.CacheConfig(
threadsCachingIntervalSeconds == null
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import java.lang.invoke.MethodHandles;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
Expand All @@ -34,7 +35,6 @@
import org.apache.solr.common.ConfigNode;
import org.apache.solr.common.SolrException;
import org.apache.solr.common.cloud.SolrClassLoader;
import org.apache.solr.common.util.DOMUtil;
import org.apache.solr.core.SolrConfig;
import org.apache.solr.util.plugin.AbstractPluginLoader;
import org.slf4j.Logger;
Expand Down Expand Up @@ -74,19 +74,19 @@ protected FieldType create(SolrClassLoader loader, String name, String className
FieldType ft = loader.newInstance(className, FieldType.class);
ft.setTypeName(name);

ConfigNode anode = node.child(it -> "query".equals(it.attributes().get("type")), "analyzer");
ConfigNode anode = node.child("analyzer", it -> "query".equals(it.attributes().get("type")));
Analyzer queryAnalyzer = readAnalyzer(anode);

anode = node.child(it -> "multiterm".equals(it.attributes().get("type")), "analyzer");
anode = node.child("analyzer", it -> "multiterm".equals(it.attributes().get("type")));
Analyzer multiAnalyzer = readAnalyzer(anode);

// An analyzer without a type specified, or with type="index"
anode =
node.child(
"analyzer",
it ->
(it.attributes().get("type") == null
|| "index".equals(it.attributes().get("type"))),
"analyzer");
|| "index".equals(it.attributes().get("type"))));
Analyzer analyzer = readAnalyzer(anode);

// a custom similarity[Factory]
Expand Down Expand Up @@ -144,9 +144,7 @@ protected FieldType create(SolrClassLoader loader, String name, String className

@Override
protected void init(FieldType plugin, ConfigNode node) throws Exception {

Map<String, String> params = DOMUtil.toMapExcept(node, NAME);
plugin.setArgs(schema, params);
plugin.setArgs(schema, node.attributesExcept(NAME));
}

@Override
Expand Down Expand Up @@ -185,7 +183,7 @@ private Analyzer readAnalyzer(ConfigNode node) {
// parent node used to be passed in as "fieldtype"

if (node == null) return null;
String analyzerName = DOMUtil.getAttr(node, "class", null);
String analyzerName = node.attr("class");

// check for all of these up front, so we can error if used in
// conjunction with an explicit analyzer class.
Expand Down Expand Up @@ -213,7 +211,7 @@ private Analyzer readAnalyzer(ConfigNode node) {
final Class<? extends Analyzer> clazz = loader.findClass(analyzerName, Analyzer.class);
Analyzer analyzer = clazz.getConstructor().newInstance();

final String matchVersionStr = DOMUtil.getAttr(node, LUCENE_MATCH_VERSION_PARAM, null);
final String matchVersionStr = node.attr(LUCENE_MATCH_VERSION_PARAM);
final Version luceneMatchVersion =
(matchVersionStr == null)
? schema.getDefaultLuceneMatchVersion()
Expand Down Expand Up @@ -246,7 +244,7 @@ private Analyzer readAnalyzer(ConfigNode node) {
protected CharFilterFactory create(
SolrClassLoader loader, String name, String className, ConfigNode node)
throws Exception {
final Map<String, String> params = DOMUtil.toMapExcept(node);
final Map<String, String> params = new HashMap<>(node.attributes());
String configuredVersion = params.remove(LUCENE_MATCH_VERSION_PARAM);
params.put(
LUCENE_MATCH_VERSION_PARAM,
Expand Down Expand Up @@ -310,7 +308,7 @@ protected CharFilterFactory register(String name, CharFilterFactory plugin) {
protected TokenizerFactory create(
SolrClassLoader loader, String name, String className, ConfigNode node)
throws Exception {
final Map<String, String> params = DOMUtil.toMap(node);
final Map<String, String> params = new HashMap<>(node.attributes());
String configuredVersion = params.remove(LUCENE_MATCH_VERSION_PARAM);
params.put(
LUCENE_MATCH_VERSION_PARAM,
Expand Down Expand Up @@ -381,7 +379,7 @@ protected TokenizerFactory register(String name, TokenizerFactory plugin) {
protected TokenFilterFactory create(
SolrClassLoader loader, String name, String className, ConfigNode node)
throws Exception {
final Map<String, String> params = DOMUtil.toMap(node);
final Map<String, String> params = new HashMap<>(node.attributes());
String configuredVersion = params.remove(LUCENE_MATCH_VERSION_PARAM);
params.put(
LUCENE_MATCH_VERSION_PARAM,
Expand Down
25 changes: 12 additions & 13 deletions solr/core/src/java/org/apache/solr/schema/IndexSchema.java
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,6 @@
import org.apache.solr.common.params.ModifiableSolrParams;
import org.apache.solr.common.params.SolrParams;
import org.apache.solr.common.util.Cache;
import org.apache.solr.common.util.DOMUtil;
import org.apache.solr.common.util.NamedList;
import org.apache.solr.common.util.Pair;
import org.apache.solr.common.util.SimpleOrderedMap;
Expand Down Expand Up @@ -532,9 +531,9 @@ protected void readSchema(ConfigSetService.ConfigResource is) {
final FieldTypePluginLoader typeLoader =
new FieldTypePluginLoader(this, fieldTypes, schemaAware);

List<ConfigNode> fTypes = rootNode.getAll(null, FIELDTYPE_KEYS);
List<ConfigNode> fTypes = rootNode.getAll(FIELDTYPE_KEYS, null);
ConfigNode types = rootNode.child(TYPES);
if (types != null) fTypes.addAll(types.getAll(null, FIELDTYPE_KEYS));
if (types != null) fTypes.addAll(types.getAll(FIELDTYPE_KEYS, null));
typeLoader.load(solrClassLoader, fTypes);

// load the fields
Expand Down Expand Up @@ -574,7 +573,7 @@ protected void readSchema(ConfigSetService.ConfigResource is) {
}

node =
rootNode.child(it -> it.attributes().get("defaultOperator") != null, "solrQueryParser");
rootNode.child("solrQueryParser", it -> it.attributes().get("defaultOperator") != null);
if (node != null) {
throw new SolrException(
ErrorCode.SERVER_ERROR,
Expand Down Expand Up @@ -697,17 +696,17 @@ protected synchronized Map<String, Boolean> loadFields(ConfigNode n) {

ArrayList<DynamicField> dFields = new ArrayList<>();

List<ConfigNode> nodes = n.getAll(null, FIELD_KEYS);
List<ConfigNode> nodes = n.getAll(FIELD_KEYS, null);
ConfigNode child = n.child(FIELDS);
if (child != null) {
nodes = new ArrayList<>(nodes);
nodes.addAll(child.getAll(null, FIELD_KEYS));
nodes.addAll(child.getAll(FIELD_KEYS, null));
}

for (ConfigNode node : nodes) {
String name = DOMUtil.getAttr(node, NAME, "field definition");
String name = node.attrRequired(NAME, "field definition");
log.trace("reading field def {}", name);
String type = DOMUtil.getAttr(node, TYPE, "field " + name);
String type = node.attrRequired(TYPE, "field " + name);

FieldType ft = fieldTypes.get(type);
if (ft == null) {
Expand All @@ -716,7 +715,7 @@ protected synchronized Map<String, Boolean> loadFields(ConfigNode n) {
"Unknown " + FIELD_TYPE + " '" + type + "' specified on field " + name);
}

Map<String, String> args = DOMUtil.toMapExcept(node, NAME, TYPE);
Map<String, String> args = node.attributesExcept(NAME, TYPE);
if (null != args.get(REQUIRED)) {
explicitRequiredProp.put(name, Boolean.valueOf(args.get(REQUIRED)));
}
Expand Down Expand Up @@ -793,9 +792,9 @@ protected synchronized void loadCopyFields(ConfigNode n) {
}
for (ConfigNode node : nodes) {

String source = DOMUtil.getAttr(node, SOURCE, COPY_FIELD + " definition");
String dest = DOMUtil.getAttr(node, DESTINATION, COPY_FIELD + " definition");
String maxChars = DOMUtil.getAttr(node, MAX_CHARS, null);
String source = node.attrRequired(SOURCE, COPY_FIELD + " definition");
String dest = node.attrRequired(DESTINATION, COPY_FIELD + " definition");
String maxChars = node.attr(MAX_CHARS);

int maxCharsInt = CopyField.UNLIMITED;
if (maxChars != null) {
Expand Down Expand Up @@ -1089,7 +1088,7 @@ static SimilarityFactory readSimilarity(SolrClassLoader loader, ConfigNode node)
final Object obj = loader.newInstance(classArg, Object.class, "search.similarities.");
if (obj instanceof SimilarityFactory) {
// configure a factory, get a similarity back
final NamedList<Object> namedList = DOMUtil.childNodesToNamedList(node);
final NamedList<Object> namedList = node.childNodesToNamedList();
namedList.add(SimilarityFactory.CLASS_NAME, classArg);
SolrParams params = namedList.toSolrParams();
similarityFactory = (SimilarityFactory) obj;
Expand Down
10 changes: 5 additions & 5 deletions solr/core/src/java/org/apache/solr/util/DOMConfigNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,11 @@
public class DOMConfigNode implements ConfigNode {

private final Node node;
Map<String, String> attrs;
private Map<String, String> attrs; // lazy populated

public DOMConfigNode(Node node) {
this.node = node;
}

@Override
public String name() {
Expand All @@ -42,10 +46,6 @@ public String txt() {
return DOMUtil.getText(node);
}

public DOMConfigNode(Node node) {
this.node = node;
}

@Override
public Map<String, String> attributes() {
if (attrs != null) return attrs;
Expand Down
8 changes: 6 additions & 2 deletions solr/core/src/java/org/apache/solr/util/DataConfigNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -94,9 +94,13 @@ public List<ConfigNode> getAll(String name) {
}

@Override
public List<ConfigNode> getAll(Predicate<ConfigNode> test, Set<String> matchNames) {
public List<ConfigNode> getAll(Set<String> names, Predicate<ConfigNode> test) {
if (names == null) {
return ConfigNode.super.getAll(names, test);
}
// fast implementation based on our index on named children:
List<ConfigNode> result = new ArrayList<>();
for (String s : matchNames) {
for (String s : names) {
List<ConfigNode> vals = kids.get(s);
if (vals != null) {
vals.forEach(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
import org.apache.solr.common.SolrException;
import org.apache.solr.common.SolrException.ErrorCode;
import org.apache.solr.common.cloud.SolrClassLoader;
import org.apache.solr.common.util.DOMUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand Down Expand Up @@ -133,9 +132,9 @@ public T load(SolrClassLoader loader, List<ConfigNode> nodes) {
for (ConfigNode node : nodes) {
String name = null;
try {
name = DOMUtil.getAttr(node, NAME, requireName ? type : null);
String className = DOMUtil.getAttr(node, "class", null);
String defaultStr = DOMUtil.getAttr(node, "default", null);
name = requireName ? node.attrRequired(NAME, type) : node.attr(NAME);
String className = node.attr("class");
String defaultStr = node.attr("default");

if (Objects.isNull(className) && Objects.isNull(name)) {
throw new RuntimeException(type + ": missing mandatory attribute 'class' or 'name'");
Expand Down Expand Up @@ -219,8 +218,8 @@ public T loadSingle(SolrClassLoader loader, ConfigNode node) {
T plugin = null;

try {
String name = DOMUtil.getAttr(node, NAME, requireName ? type : null);
String className = DOMUtil.getAttr(node, "class", type);
String name = requireName ? node.attrRequired(NAME, type) : node.attr(NAME);
String className = node.attrRequired("class", type);
plugin = create(loader, name, className, node);
if (log.isDebugEnabled()) {
log.debug("created {}: {}", name, plugin.getClass().getName());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@

import java.util.Map;
import org.apache.solr.common.ConfigNode;
import org.apache.solr.common.util.DOMUtil;

/**
* @since solr 1.3
Expand All @@ -35,7 +34,7 @@ public MapPluginLoader(String name, Class<T> pluginClassType, Map<String, T> map

@Override
protected void init(T plugin, ConfigNode node) throws Exception {
Map<String, String> params = DOMUtil.toMapExcept(node, NAME, "class");
Map<String, String> params = node.attributesExcept(NAME, "class");
plugin.init(params);
}

Expand Down
Loading

0 comments on commit d27b171

Please sign in to comment.