All Downloads are FREE. Search and download functionalities are using the official Maven repository.

aQute.bnd.xmlattribute.XMLAttributeFinder Maven / Gradle / Ivy

There is a newer version: 7.0.0
Show newest version
package aQute.bnd.xmlattribute;

import java.lang.reflect.Array;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

import aQute.bnd.annotation.xml.XMLAttribute;
import aQute.bnd.osgi.Analyzer;
import aQute.bnd.osgi.Annotation;
import aQute.bnd.osgi.ClassDataCollector;
import aQute.bnd.osgi.Clazz;
import aQute.bnd.osgi.Descriptors.TypeRef;

public class XMLAttributeFinder extends ClassDataCollector {

	private final Analyzer			analyzer;

	Map		annoCache		= new HashMap();
	Map>	defaultsCache	= new HashMap>();

	public XMLAttributeFinder(Analyzer analyzer) {
		this.analyzer = analyzer;
	}

	public synchronized XMLAttribute getXMLAttribute(Annotation a) throws Exception {
		TypeRef name = a.getName();
		if (annoCache.containsKey(name))
			return annoCache.get(name);
		Clazz clazz = analyzer.findClass(name);
		if (clazz != null) {
			xmlAttr = null;
			clazz.parseClassFileWithCollector(this);
			annoCache.put(name, xmlAttr);
			return xmlAttr;
		}
		return null;
	}

	XMLAttribute xmlAttr;

	@Override
	public void annotation(Annotation annotation) throws Exception {
		java.lang.annotation.Annotation a = annotation.getAnnotation();
		if (a instanceof XMLAttribute)
			xmlAttr = (XMLAttribute) a;
	}

	public Map getDefaults(Annotation a) {
		TypeRef name = a.getName();
		Map defaults = defaultsCache.get(name);
		if (defaults == null)
			defaults = extractDefaults(name, analyzer);
		if (defaults == null)
			return new LinkedHashMap();
		return new LinkedHashMap(defaults);
	}

	private Map extractDefaults(TypeRef name, final Analyzer analyzer) {
		try {
			Clazz clazz = analyzer.findClass(name);
			final Map props = new LinkedHashMap();
			clazz.parseClassFileWithCollector(new ClassDataCollector() {

				@Override
				public void annotationDefault(Clazz.MethodDef defined) {
					Object value = defined.getConstant();
					// check type, exit with warning if annotation or annotation
					// array
					boolean isClass = false;
					TypeRef type = defined.getType().getClassRef();
					if (!type.isPrimitive()) {
						if (Class.class.getName().equals(type.getFQN())) {
							isClass = true;
						} else {
							try {
								Clazz r = analyzer.findClass(type);
								if (r.isAnnotation()) {
									analyzer.warning("Nested annotation type found in field %s, %s", defined.getName(),
											type.getFQN());
									return;
								}
							} catch (Exception e) {
								analyzer.exception(e, "Exception extracting annotation defaults for type %s", type);
								return;
							}
						}
					}
					if (value != null) {
						String name = defined.getName();
						if (value.getClass().isArray()) {
							StringBuilder sb = new StringBuilder();
							String sep = "";
							// add element individually
							for (int i = 0; i < Array.getLength(value); i++) {
								Object element = Array.get(value, i);
								sb.append(sep).append(convert(element, isClass));
								sep = " ";
							}
							props.put(name, sb.toString());
						} else {
							props.put(name, convert(value, isClass));
						}
					}
				}

				private String convert(Object value, boolean isClass) {
					if (isClass)
						return ((TypeRef) value).getFQN();
					return String.valueOf(value);
				}

			});
			defaultsCache.put(name, props);
			return props;
		} catch (Exception e) {
			analyzer.exception(e, "Exception extracting annotation defaults for type %s", name);
		}
		return null;
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy