![JAR search and dependency download from the Maven repository](/logo.png)
aQute.bnd.osgi.Annotation Maven / Gradle / Ivy
Show all versions of biz.aQute.bnd Show documentation
package aQute.bnd.osgi;
import static java.util.Objects.requireNonNull;
import java.lang.annotation.RetentionPolicy;
import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.stream.Stream;
import aQute.bnd.osgi.Descriptors.TypeRef;
import aQute.lib.converter.Converter;
/*
* This class is referenced in aQute.bnd.annotation.metatype.Configurable in constant
* BND_ANNOTATION_CLASS_NAME
*/
public class Annotation {
/**
* Bnd ElememtType
*
* We use this instead of java.lang.annotation.ElementType so we can
* reference element types introduced in versions of Java later than the
* current compile/runtime version of Java.
*/
public enum ElementType {
TYPE, // Java 5
FIELD, // Java 5
METHOD, // Java 5
PARAMETER, // Java 5
CONSTRUCTOR, // Java 5
LOCAL_VARIABLE, // Java 5
ANNOTATION_TYPE, // Java 5
PACKAGE, // Java 5
TYPE_PARAMETER, // Java 8
TYPE_USE, // Java 8
MODULE; // Java 9
}
private static final Converter CONVERTER;
static {
CONVERTER = new Converter();
CONVERTER.hook(null, (t, o) -> {
if (o instanceof Annotation a && t instanceof Class> c && c.isAnnotation()) {
@SuppressWarnings("unchecked")
Class ac = (Class) c;
return a.getAnnotation(ac);
}
return null;
});
}
private final TypeRef name;
private Map elements;
private final ElementType member;
private final RetentionPolicy policy;
public Annotation(TypeRef name, Map elements, ElementType member, RetentionPolicy policy) {
this.name = requireNonNull(name);
this.elements = elements;
this.member = requireNonNull(member);
this.policy = requireNonNull(policy);
}
public TypeRef getName() {
return name;
}
public ElementType elementType() {
return member;
}
public RetentionPolicy getRetentionPolicy() {
return policy;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(name)
.append(':')
.append(member)
.append(':')
.append(policy)
.append(':')
.append('{');
if (elements != null) {
Iterator> i = elements.entrySet()
.iterator();
if (i.hasNext()) {
for (Entry e = i.next();; e = i.next()) {
sb.append(e.getKey())
.append('=');
Object v = e.getValue();
if (v instanceof Object[] array) {
sb.append(Arrays.toString(array));
} else {
sb.append(v);
}
if (!i.hasNext()) {
break;
}
sb.append(',')
.append(' ');
}
}
}
return sb.append('}')
.toString();
}
@SuppressWarnings("unchecked")
public T get(String string) {
if (elements == null) {
return null;
}
return (T) elements.get(string);
}
public Stream stream(String key, Class extends T> type) {
Object v = get(key);
if (v == null) {
return Stream.empty();
}
if (v.getClass()
.isArray()) {
return Arrays.stream((Object[]) v)
.map(type::cast);
}
return Stream.of(v)
.map(type::cast);
}
public void put(String string, Object v) {
if (elements == null) {
elements = new LinkedHashMap<>();
}
elements.put(string, v);
}
public boolean containsKey(String key) {
if (elements == null) {
return false;
}
return elements.containsKey(key);
}
public Set keySet() {
if (elements == null) {
return Collections.emptySet();
}
return elements.keySet();
}
public Set> entrySet() {
if (elements == null) {
return Collections.emptySet();
}
return elements.entrySet();
}
public T getAnnotation() throws Exception {
return getAnnotation(getClass().getClassLoader());
}
public T getAnnotation(ClassLoader cl) throws Exception {
String cname = name.getFQN();
try {
@SuppressWarnings("unchecked")
Class c = (Class) cl.loadClass(cname);
return getAnnotation(c);
} catch (ClassNotFoundException | NoClassDefFoundError e) {
return null;
}
}
public T getAnnotation(Class c) throws Exception {
if (elements == null) {
elements = new LinkedHashMap<>();
}
return CONVERTER.convert(c, elements);
}
public void merge(Annotation annotation) {
merge(annotation.elements);
}
public void addDefaults(Clazz c) throws Exception {
merge(c.getDefaults());
}
private void merge(Map map) {
if (map == null || map.isEmpty()) {
return;
}
if (elements == null) {
elements = new LinkedHashMap<>(map);
} else {
map.forEach(elements::putIfAbsent);
}
}
}