blob: ec5d5c002137ffaf9a1fd93865566339a9abe3cb [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.index;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import org.apache.lucene.index.MergePolicy;
import org.apache.solr.core.SolrResourceLoader;
import org.apache.solr.schema.IndexSchema;
/**
* A {@link MergePolicyFactory} for wrapping additional {@link MergePolicyFactory factories}.
*/
public abstract class WrapperMergePolicyFactory extends MergePolicyFactory {
private static final String CLASS = "class";
protected static final String[] NO_SUB_PACKAGES = new String[0];
static final String WRAPPED_PREFIX = "wrapped.prefix"; // not private so that test(s) can use it
private final MergePolicyFactoryArgs wrappedMergePolicyArgs;
private final String wrappedMergePolicyClassName;
protected WrapperMergePolicyFactory(SolrResourceLoader resourceLoader, MergePolicyFactoryArgs args, IndexSchema schema) {
super(resourceLoader, args, schema);
wrappedMergePolicyArgs = filterWrappedMergePolicyFactoryArgs();
if (wrappedMergePolicyArgs == null) {
wrappedMergePolicyClassName = null;
} else {
wrappedMergePolicyClassName = (String) wrappedMergePolicyArgs.remove(CLASS);
if (wrappedMergePolicyClassName == null) {
throw new IllegalArgumentException("Class name not defined for wrapped MergePolicyFactory!");
}
}
if (wrappedMergePolicyArgs != null) {
final Set<String> overshadowedWrappedMergePolicyArgs = new HashSet<>(wrappedMergePolicyArgs.keys());
overshadowedWrappedMergePolicyArgs.retainAll(args.keys());
if (!overshadowedWrappedMergePolicyArgs.isEmpty()) {
throw new IllegalArgumentException("Wrapping and wrapped merge policy args overlap! "+overshadowedWrappedMergePolicyArgs);
}
}
}
/**
* Returns the default wrapped {@link MergePolicy}. This is called if the factory settings do not explicitly specify
* the wrapped policy.
*/
protected MergePolicy getDefaultWrappedMergePolicy() {
final MergePolicyFactory mpf = new DefaultMergePolicyFactory();
return mpf.getMergePolicy();
}
/** Returns an instance of the wrapped {@link MergePolicy} after it has been configured with all set parameters. */
@SuppressWarnings({"rawtypes"})
protected final MergePolicy getWrappedMergePolicy() {
if (wrappedMergePolicyArgs == null) {
return getDefaultWrappedMergePolicy();
}
final MergePolicyFactory mpf = resourceLoader.newInstance(
wrappedMergePolicyClassName,
MergePolicyFactory.class,
NO_SUB_PACKAGES,
new Class[] {SolrResourceLoader.class, MergePolicyFactoryArgs.class, IndexSchema.class},
new Object[] {resourceLoader, wrappedMergePolicyArgs, schema});
return mpf.getMergePolicy();
}
/** Returns an instance of the wrapping {@link MergePolicy} without configuring its set parameters. */
protected abstract MergePolicy getMergePolicyInstance(MergePolicy wrappedMP);
/** Returns a wrapping {@link MergePolicy} with its set parameters configured. */
@Override
public final MergePolicy getMergePolicy() {
final MergePolicy wrappedMP = getWrappedMergePolicy();
final MergePolicy mp = getMergePolicyInstance(wrappedMP);
args.invokeSetters(mp);
return mp;
}
/**
* Returns a {@link MergePolicyFactoryArgs} for the wrapped {@link MergePolicyFactory}. This method also removes all
* args from this instance's args.
*/
private MergePolicyFactoryArgs filterWrappedMergePolicyFactoryArgs() {
final String wrappedPolicyPrefix = (String) args.remove(WRAPPED_PREFIX);
if (wrappedPolicyPrefix == null) {
return null;
}
final String baseArgsPrefix = wrappedPolicyPrefix + '.';
final int baseArgsPrefixLength = baseArgsPrefix.length();
final MergePolicyFactoryArgs wrappedArgs = new MergePolicyFactoryArgs();
for (final Iterator<String> iter = args.keys().iterator(); iter.hasNext();) {
final String key = iter.next();
if (key.startsWith(baseArgsPrefix)) {
wrappedArgs.add(key.substring(baseArgsPrefixLength), args.get(key));
iter.remove();
}
}
return wrappedArgs;
}
}