package aQute.bnd.metatype;
import java.util.Arrays;
import java.util.Map;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.metatype.annotations.Designate;
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;
import aQute.bnd.xmlattribute.XMLAttributeFinder;
public class DesignateReader extends ClassDataCollector {
private Analyzer analyzer;
private Clazz clazz;
private Map<TypeRef,OCDDef> classToOCDMap;
private String[] pids;
private String pid;
private Annotation designate;
private final XMLAttributeFinder finder;
private DesignateDef def;
DesignateReader(Analyzer analyzer, Clazz clazz, Map<TypeRef,OCDDef> classToOCDMap, XMLAttributeFinder finder) {
this.analyzer = analyzer;
this.clazz = clazz;
this.classToOCDMap = classToOCDMap;
this.finder = finder;
}
static DesignateDef getDesignate(Clazz c, Analyzer analyzer, Map<TypeRef,OCDDef> classToOCDMap,
XMLAttributeFinder finder) throws Exception {
DesignateReader r = new DesignateReader(analyzer, c, classToOCDMap, finder);
return r.getDef();
}
private DesignateDef getDef() throws Exception {
clazz.parseClassFileWithCollector(this);
if (pid != null && designate != null) {
if (pids != null && pids.length > 1) {
analyzer.error(
"DS Component %s specifies multiple pids %s, and a Designate which requires exactly one pid",
clazz.getClassName().getFQN(), Arrays.asList(pids));
return null;
}
TypeRef ocdClass = designate.get("ocd");
// ocdClass = ocdClass.substring(1, ocdClass.length() - 1);
OCDDef ocd = classToOCDMap.get(ocdClass);
if (ocd == null) {
analyzer.error("DS Component %s specifies ocd class %s which cannot be found; known classes %s",
clazz.getClassName().getFQN(), ocdClass, classToOCDMap.keySet());
return null;
}
String id = ocd.id;
boolean factoryPid = Boolean.TRUE == designate.get("factory");
if (def == null)
def = new DesignateDef(finder);
def.ocdRef = id;
def.pid = pid;
def.factory = factoryPid;
ocd.designates.add(def);
return def;
}
return null;
}
@Override
public void annotation(Annotation annotation) throws Exception {
try {
java.lang.annotation.Annotation a = annotation.getAnnotation();
if (a instanceof Designate)
designate = annotation;
else if (a instanceof Component) {
doComponent(a);
} else {
XMLAttribute xmlAttr = finder.getXMLAttribute(annotation);
if (xmlAttr != null) {
doXmlAttribute(annotation, xmlAttr);
}
}
} catch (Exception e) {
e.printStackTrace();
analyzer.error("During generation of a component on class %s, exception %s", clazz, e);
}
}
void doComponent(java.lang.annotation.Annotation a) {
Component component = (Component) a;
pids = component.configurationPid();
if (pids != null) {
pid = pids[0];
}
if (pids == null || "$".equals(pid)) {
pid = component.name();
if (pid == null)
pid = clazz.getClassName().getFQN();
}
}
private void doXmlAttribute(Annotation annotation, XMLAttribute xmlAttr) {
if (def == null)
def = new DesignateDef(finder);
def.addExtensionAttribute(xmlAttr, annotation);
}
}