blob: 76b252bea8c7a40efadaafcf8ee0de879c10a97f [file] [log] [blame]
/*
* 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.
*/
package org.apache.solr.core;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import com.google.common.collect.ImmutableSet;
import org.apache.solr.common.util.NamedList;
import org.apache.solr.common.util.StrUtils;
import static org.apache.solr.common.params.CommonParams.NAME;
import static org.apache.solr.common.params.CommonParams.PATH;
import static org.apache.solr.core.PluginInfo.APPENDS;
import static org.apache.solr.core.PluginInfo.DEFAULTS;
import static org.apache.solr.core.PluginInfo.INVARIANTS;
/**
* An Object which represents a {@code <initParams>} tag
*/
public class InitParams {
public static final String TYPE = "initParams";
public final String name;
public final Set<String> paths;
@SuppressWarnings({"rawtypes"})
public final NamedList defaults;
@SuppressWarnings({"rawtypes"})
public final NamedList invariants;
@SuppressWarnings({"rawtypes"})
public final NamedList appends;
final private PluginInfo pluginInfo;
private final Set<String> KNOWN_KEYS = ImmutableSet.of(DEFAULTS, INVARIANTS, APPENDS);
public InitParams(PluginInfo p) {
this.pluginInfo = p;
this.name = p.attributes.get(NAME);
Set<String> paths = null;
String pathStr = p.attributes.get(PATH);
if (pathStr != null) {
paths = Collections.unmodifiableSet(new HashSet<>(StrUtils.splitSmart(pathStr, ',')));
}
this.paths = paths;
@SuppressWarnings({"rawtypes"})
NamedList nl = (NamedList) p.initArgs.get(DEFAULTS);
defaults = nl == null ? null : nl.getImmutableCopy();
nl = (NamedList) p.initArgs.get(INVARIANTS);
invariants = nl == null ? null : nl.getImmutableCopy();
nl = (NamedList) p.initArgs.get(APPENDS);
appends = nl == null ? null : nl.getImmutableCopy();
}
public boolean matchPath(String name) {
if (paths == null) return false;
if (paths.contains(name)) return true;
for (String path : paths) {
if (matchPath(path, name)) return true;
}
return false;
}
private static boolean matchPath(String path, String name) {
List<String> pathSplit = StrUtils.splitSmart(path, '/');
List<String> nameSplit = StrUtils.splitSmart(name, '/');
int i = 0;
for (; i < nameSplit.size(); i++) {
String s = nameSplit.get(i);
String ps = pathSplit.size() > i ? pathSplit.get(i) : null;
if (ps == null) return false;
if (s.equals(ps)) continue;
if ("*".equals(ps) && nameSplit.size() == i + 1) return true;
if ("**".equals(ps)) return true;
return false;
}
String ps = pathSplit.size() > i ? pathSplit.get(i) : null;
return "*".equals(ps) || "**".equals(ps);
}
@SuppressWarnings({"unchecked", "rawtypes"})
public void apply(PluginInfo info) {
if (!info.isFromSolrConfig()) {
//if this is a component implicitly defined in code it should be overridden by initPrams
merge(defaults, (NamedList) info.initArgs.get(DEFAULTS), info.initArgs, DEFAULTS, false);
} else {
//if the args is initialized from solrconfig.xml inside the requestHandler it should be taking precedence over initParams
merge((NamedList) info.initArgs.get(DEFAULTS), defaults, info.initArgs, DEFAULTS, false);
}
merge((NamedList) info.initArgs.get(INVARIANTS), invariants, info.initArgs, INVARIANTS, false);
merge((NamedList) info.initArgs.get(APPENDS), appends, info.initArgs, APPENDS, true);
if (pluginInfo.initArgs != null) {
for (int i = 0; i < pluginInfo.initArgs.size(); i++) {
String name = pluginInfo.initArgs.getName(i);
if (KNOWN_KEYS.contains(name)) continue;//already taken care of
Object val = info.initArgs.get(name);
if (val != null) continue; //this is explicitly specified in the reqhandler , ignore
info.initArgs.add(name, pluginInfo.initArgs.getVal(i));
}
}
}
@SuppressWarnings({"unchecked", "rawtypes"})
private static void merge(NamedList first, NamedList second, NamedList sink, String name, boolean appends) {
if (first == null && second == null) return;
if (first == null) first = new NamedList();
NamedList nl = first.clone();
if (appends) {
if (second != null) nl.addAll(second);
} else {
Set<String> a = new HashSet<>();
Set<String> b = new HashSet<>();
for (Object o : first) {
Map.Entry<String, Object> e = (Map.Entry) o;
a.add(e.getKey());
}
if (second != null) {
for (Object o : second) {
Map.Entry<String, Object> e = (Map.Entry) o;
b.add(e.getKey());
}
}
for (String s : b) {
if (a.contains(s)) continue;
for (Object v : second.getAll(s)) nl.add(s, v);
}
}
if (sink.indexOf(name, 0) > -1) {
sink.setVal(sink.indexOf(name, 0), nl);
} else {
sink.add(name, nl);
}
}
}