brooklyn.entity.proxying.BasicEntitySpec Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of brooklyn-core Show documentation
Show all versions of brooklyn-core Show documentation
Entity implementation classes, events, and other core elements
package brooklyn.entity.proxying;
import static com.google.common.base.Preconditions.checkNotNull;
import java.lang.reflect.Modifier;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import brooklyn.config.ConfigKey;
import brooklyn.config.ConfigKey.HasConfigKey;
import brooklyn.entity.Entity;
import brooklyn.management.Task;
import brooklyn.policy.Policy;
import brooklyn.util.exceptions.Exceptions;
import com.google.common.base.Objects;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
public class BasicEntitySpec> implements EntitySpec {
private static final Logger log = LoggerFactory.getLogger(BasicEntitySpec.ConcreteEntitySpec.class);
private static class ConcreteEntitySpec extends BasicEntitySpec> {
ConcreteEntitySpec(Class type) {
super(type);
}
}
public static BasicEntitySpec newInstance(Class type) {
return new ConcreteEntitySpec(type);
}
public static BasicEntitySpec newInstance(Class type, Class implType) {
return new ConcreteEntitySpec(type).impl(implType);
}
private final Class type;
private String displayName;
private Class extends T> impl;
private Entity parent;
private final Map flags = Maps.newLinkedHashMap();
private final Map, Object> config = Maps.newLinkedHashMap();
private final List policies = Lists.newArrayList();
private final Set> additionalInterfaces = Sets.newLinkedHashSet();
public BasicEntitySpec(Class type) {
this.type = type;
}
@SuppressWarnings("unchecked")
protected S self() {
return (S) this;
}
public S displayName(String val) {
displayName = val;
return self();
}
public S impl(Class extends T> val) {
checkIsImplementation(checkNotNull(val, "impl"));
checkIsNewStyleImplementation(val);
impl = val;
return self();
}
public S additionalInterfaces(Class>... vals) {
for (Class> val : vals) {
additionalInterfaces.add(val);
}
return self();
}
public S additionalInterfaces(Iterable> val) {
additionalInterfaces.addAll(Sets.newLinkedHashSet(val));
return self();
}
public S parent(Entity val) {
parent = checkNotNull(val, "parent");
return self();
}
public S configure(Map,?> val) {
for (Map.Entry, ?> entry: val.entrySet()) {
if (entry.getKey()==null) throw new NullPointerException("Null key not permitted");
if (entry.getKey() instanceof CharSequence)
flags.put(entry.getKey().toString(), entry.getValue());
else if (entry.getKey() instanceof ConfigKey>)
config.put((ConfigKey>)entry.getKey(), entry.getValue());
else if (entry.getKey() instanceof HasConfigKey>)
config.put(((HasConfigKey>)entry.getKey()).getConfigKey(), entry.getValue());
else {
log.warn("Spec "+this+" ignoring unknown config key "+entry.getKey());
}
}
return self();
}
public S configure(CharSequence key, Object val) {
flags.put(checkNotNull(key, "key").toString(), val);
return self();
}
public S configure(ConfigKey key, V val) {
config.put(checkNotNull(key, "key"), val);
return self();
}
public S configure(ConfigKey key, Task extends V> val) {
config.put(checkNotNull(key, "key"), val);
return self();
}
public S configure(HasConfigKey key, V val) {
config.put(checkNotNull(key, "key").getConfigKey(), val);
return self();
}
public S configure(HasConfigKey key, Task extends V> val) {
config.put(checkNotNull(key, "key").getConfigKey(), val);
return self();
}
public S policy(Policy val) {
policies.add(val);
return self();
}
@Override
public Class getType() {
return type;
}
@Override
public String getDisplayName() {
return displayName;
}
@Override
public Class extends T> getImplementation() {
return impl;
}
public Set> getAdditionalInterfaces() {
return additionalInterfaces;
}
@Override
public Entity getParent() {
return parent;
}
@Override
public Map getFlags() {
return Collections.unmodifiableMap(flags);
}
@Override
public Map, Object> getConfig() {
return Collections.unmodifiableMap(config);
}
@Override
public List getPolicies() {
return policies;
}
@Override
public String toString() {
return Objects.toStringHelper(this).add("type", type).toString();
}
// TODO Duplicates method in BasicEntityTypeRegistry
private void checkIsImplementation(Class> val) {
if (!type.isAssignableFrom(val)) throw new IllegalStateException("Implementation "+val+" does not implement "+type);
if (val.isInterface()) throw new IllegalStateException("Implementation "+val+" is an interface, but must be a non-abstract class");
if (Modifier.isAbstract(val.getModifiers())) throw new IllegalStateException("Implementation "+val+" is abstract, but must be a non-abstract class");
}
// TODO Duplicates method in BasicEntityTypeRegistry, and InternalEntityFactory.isNewStyleEntity
private void checkIsNewStyleImplementation(Class> implClazz) {
try {
implClazz.getConstructor(new Class[0]);
} catch (NoSuchMethodException e) {
throw new IllegalStateException("Implementation "+implClazz+" must have a no-argument constructor");
} catch (SecurityException e) {
throw Exceptions.propagate(e);
}
if (implClazz.isInterface()) throw new IllegalStateException("Implementation "+implClazz+" is an interface, but must be a non-abstract class");
if (Modifier.isAbstract(implClazz.getModifiers())) throw new IllegalStateException("Implementation "+implClazz+" is abstract, but must be a non-abstract class");
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy