org.apache.druid.guice.ConditionalMultibind Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of druid-processing Show documentation
Show all versions of druid-processing Show documentation
A module that is everything required to understands Druid Segments
/*
* 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.druid.guice;
import com.google.common.base.Predicate;
import com.google.inject.Binder;
import com.google.inject.TypeLiteral;
import com.google.inject.multibindings.Multibinder;
import org.apache.druid.guice.annotations.PublicApi;
import javax.annotation.Nullable;
import java.lang.annotation.Annotation;
import java.util.Properties;
/**
* Provides the ability to conditionally bind an item to a set. The condition is based on the value set in the
* runtime.properties.
*
* Usage example:
*
* ConditionalMultibind.create(props, binder, Animal.class)
* .addConditionBinding("animal.type", Predicates.equalTo("cat"), Cat.class)
* .addConditionBinding("animal.type", Predicates.equalTo("dog"), Dog.class);
*
* At binding time, this will check the value set for property "animal.type" in props. If the value is "cat", it will
* add a binding to Cat.class. If the value is "dog", it will add a binding to Dog.class.
*
* At injection time, you will get the items that satisfy their corresponding predicates by calling
* injector.getInstance(Key.get(new TypeLiteral>(){}))
*/
@PublicApi
public class ConditionalMultibind
{
/**
* Create a ConditionalMultibind that resolves items to be added to the set at "binding" time.
*
* @param properties the runtime properties.
* @param binder the binder for the injector that is being configured.
* @param type the type that will be injected.
* @param interface type.
*
* @return An instance of ConditionalMultibind that can be used to add conditional bindings.
*/
public static ConditionalMultibind create(Properties properties, Binder binder, Class type)
{
return new ConditionalMultibind(properties, Multibinder.newSetBinder(binder, type));
}
/**
* Create a ConditionalMultibind that resolves items to be added to the set at "binding" time.
*
* @param properties the runtime properties.
* @param binder the binder for the injector that is being configured.
* @param type the type that will be injected.
* @param interface type.
* @param annotationType the binding annotation.
*
* @return An instance of ConditionalMultibind that can be used to add conditional bindings.
*/
public static ConditionalMultibind create(
Properties properties,
Binder binder,
Class type,
Class annotationType
)
{
return new ConditionalMultibind(properties, Multibinder.newSetBinder(binder, type, annotationType));
}
/**
* Create a ConditionalMultibind that resolves items to be added to the set at "binding" time.
*
* @param properties the runtime properties.
* @param binder the binder for the injector that is being configured.
* @param type the type that will be injected.
* @param interface type.
*
* @return An instance of ConditionalMultibind that can be used to add conditional bindings.
*/
public static ConditionalMultibind create(Properties properties, Binder binder, TypeLiteral type)
{
return new ConditionalMultibind(properties, Multibinder.newSetBinder(binder, type));
}
/**
* Create a ConditionalMultibind that resolves items to be added to the set at "binding" time.
*
* @param properties the runtime properties.
* @param binder the binder for the injector that is being configured.
* @param type the type that will be injected.
* @param interface type.
* @param annotationType the binding annotation.
*
* @return An instance of ConditionalMultibind that can be used to add conditional bindings.
*/
public static ConditionalMultibind create(
Properties properties,
Binder binder,
TypeLiteral type,
Class annotationType
)
{
return new ConditionalMultibind(properties, Multibinder.newSetBinder(binder, type, annotationType));
}
private final Properties properties;
private final Multibinder multibinder;
public ConditionalMultibind(Properties properties, Multibinder multibinder)
{
this.properties = properties;
this.multibinder = multibinder;
}
/**
* Unconditionally bind target to the set.
*
* @param target the target class to which it adds a binding.
*
* @return self to support a continuous syntax for adding more conditional bindings.
*/
public ConditionalMultibind addBinding(Class target)
{
multibinder.addBinding().to(target);
return this;
}
/**
* Unconditionally bind target to the set.
*
* @param target the target instance to which it adds a binding.
*
* @return self to support a continuous syntax for adding more conditional bindings.
*/
public ConditionalMultibind addBinding(T target)
{
multibinder.addBinding().toInstance(target);
return this;
}
/**
* Unconditionally bind target to the set.
*
* @param target the target type to which it adds a binding.
*
* @return self to support a continuous syntax for adding more conditional bindings.
*/
public ConditionalMultibind addBinding(TypeLiteral target)
{
multibinder.addBinding().to(target);
return this;
}
/**
* Conditionally bind target to the set. If "condition" returns true, add a binding to "target".
*
* @param property the property to inspect on
* @param condition the predicate used to verify whether to add a binding to "target"
* @param target the target class to which it adds a binding.
*
* @return self to support a continuous syntax for adding more conditional bindings.
*/
public ConditionalMultibind addConditionBinding(
String property,
Predicate condition,
Class target
)
{
return addConditionBinding(property, null, condition, target);
}
public ConditionalMultibind addConditionBinding(
String property,
String defaultValue,
Predicate condition,
Class target
)
{
if (matchCondition(property, defaultValue, condition)) {
multibinder.addBinding().to(target);
}
return this;
}
/**
* Conditionally bind target to the set. If "condition" returns true, add a binding to "target".
*
* @param property the property to inspect on
* @param condition the predicate used to verify whether to add a binding to "target"
* @param target the target instance to which it adds a binding.
*
* @return self to support a continuous syntax for adding more conditional bindings.
*/
public ConditionalMultibind addConditionBinding(
String property,
Predicate condition,
T target
)
{
if (matchCondition(property, condition)) {
multibinder.addBinding().toInstance(target);
}
return this;
}
/**
* Conditionally bind target to the set. If "condition" returns true, add a binding to "target".
*
* @param property the property to inspect on
* @param condition the predicate used to verify whether to add a binding to "target"
* @param target the target type to which it adds a binding.
*
* @return self to support a continuous syntax for adding more conditional bindings.
*/
@PublicApi
public ConditionalMultibind addConditionBinding(
String property,
Predicate condition,
TypeLiteral target
)
{
if (matchCondition(property, condition)) {
multibinder.addBinding().to(target);
}
return this;
}
public boolean matchCondition(String property, Predicate condition)
{
return matchCondition(property, null, condition);
}
public boolean matchCondition(String property, @Nullable String defaultValue, Predicate condition)
{
final String value = properties.getProperty(property, defaultValue);
if (value == null) {
return false;
}
return condition.apply(value);
}
}