use of aQute.bnd.osgi.ClassDataCollector in project bnd by bndtools.
the class CalltreeResource method writeCalltree.
/**
* Print the call tree in XML.
*
* @param out The output writer
* @param classes The set of classes
* @throws Exception Any errors
*/
public static void writeCalltree(PrintWriter out, Collection<Clazz> classes) throws Exception {
final Map<Clazz.MethodDef, Set<Clazz.MethodDef>> using = new TreeMap<Clazz.MethodDef, Set<Clazz.MethodDef>>(COMPARATOR);
final Map<Clazz.MethodDef, Set<Clazz.MethodDef>> usedby = new TreeMap<Clazz.MethodDef, Set<Clazz.MethodDef>>(COMPARATOR);
ClassDataCollector cd = new ClassDataCollector() {
// Clazz.MethodDef source;
// Before a method is parsed
@Override
public void method(Clazz.MethodDef source) {
// this.source = source;
xref(using, source, null);
xref(usedby, source, null);
}
};
for (Clazz clazz : classes) {
clazz.parseClassFileWithCollector(cd);
}
out.println("<calltree>");
xref(out, "using", using);
xref(out, "usedby", usedby);
out.println("</calltree>");
}
use of aQute.bnd.osgi.ClassDataCollector in project bnd by bndtools.
the class XMLAttributeFinder method extractDefaults.
private Map<String, String> extractDefaults(TypeRef name, final Analyzer analyzer) {
try {
Clazz clazz = analyzer.findClass(name);
final Map<String, String> props = new LinkedHashMap<String, String>();
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;
}
use of aQute.bnd.osgi.ClassDataCollector in project bnd by bndtools.
the class MetaTypeReader method parseOptionValues.
private String[] parseOptionValues(Clazz c) throws Exception {
final List<String> values = Create.list();
c.parseClassFileWithCollector(new ClassDataCollector() {
@Override
public void field(Clazz.FieldDef def) {
if (def.isEnum()) {
values.add(def.getName());
}
}
});
return values.toArray(new String[0]);
}
use of aQute.bnd.osgi.ClassDataCollector in project bnd by bndtools.
the class HeaderReader method createComponentTag.
public Tag createComponentTag(String name, String impl, Map<String, String> info) throws Exception {
final ComponentDef cd = new ComponentDef(null, AnnotationReader.V1_0);
cd.name = name;
if (info.get(COMPONENT_ENABLED) != null)
cd.enabled = Boolean.valueOf(info.get(COMPONENT_ENABLED));
cd.factory = info.get(COMPONENT_FACTORY);
if (info.get(COMPONENT_IMMEDIATE) != null)
cd.immediate = Boolean.valueOf(info.get(COMPONENT_IMMEDIATE));
if (info.get(COMPONENT_CONFIGURATION_POLICY) != null)
cd.configurationPolicy = ConfigurationPolicy.valueOf(info.get(COMPONENT_CONFIGURATION_POLICY).toUpperCase());
cd.activate = checkIdentifier(COMPONENT_ACTIVATE, info.get(COMPONENT_ACTIVATE));
cd.deactivate = checkIdentifier(COMPONENT_DEACTIVATE, info.get(COMPONENT_DEACTIVATE));
cd.modified = checkIdentifier(COMPONENT_MODIFIED, info.get(COMPONENT_MODIFIED));
cd.implementation = analyzer.getTypeRefFromFQN(impl == null ? name : impl);
String provides = info.get(COMPONENT_PROVIDE);
if (info.get(COMPONENT_SERVICEFACTORY) != null) {
if (provides != null)
cd.scope = Boolean.valueOf(info.get(COMPONENT_SERVICEFACTORY)) ? ServiceScope.BUNDLE : ServiceScope.SINGLETON;
else
warning("The servicefactory:=true directive is set but no service is provided, ignoring it");
}
if (cd.scope == ServiceScope.BUNDLE && cd.immediate != null && cd.immediate) {
// TODO can become error() if it is up to me
warning("For a Service Component, the immediate option and the servicefactory option are mutually exclusive for %s(%s)", name, impl);
}
// analyze the class for suitable methods.
final Map<String, MethodDef> lifecycleMethods = new HashMap<String, MethodDef>();
final Map<String, MethodDef> bindmethods = new HashMap<String, MethodDef>();
TypeRef typeRef = analyzer.getTypeRefFromFQN(impl);
Clazz clazz = analyzer.findClass(typeRef);
boolean privateAllowed = true;
boolean defaultAllowed = true;
String topPackage = typeRef.getPackageRef().getFQN();
while (clazz != null) {
final boolean pa = privateAllowed;
final boolean da = defaultAllowed;
final Map<String, MethodDef> classLifecyclemethods = new HashMap<String, MethodDef>();
final Map<String, MethodDef> classBindmethods = new HashMap<String, MethodDef>();
clazz.parseClassFileWithCollector(new ClassDataCollector() {
@Override
public void method(MethodDef md) {
Set<String> allowedParams = allowed;
String lifecycleName = null;
boolean isLifecycle = (cd.activate == null ? "activate" : cd.activate).equals(md.getName()) || md.getName().equals(cd.modified);
if (!isLifecycle && (cd.deactivate == null ? "deactivate" : cd.deactivate).equals(md.getName())) {
isLifecycle = true;
allowedParams = allowedDeactivate;
}
if (isLifecycle && !lifecycleMethods.containsKey(md.getName()) && (md.isPublic() || md.isProtected() || (md.isPrivate() && pa) || (!md.isPrivate()) && da) && isBetter(md, classLifecyclemethods.get(md.getName()), allowedParams)) {
classLifecyclemethods.put(md.getName(), md);
}
if (!bindmethods.containsKey(md.getName()) && (md.isPublic() || md.isProtected() || (md.isPrivate() && pa) || (!md.isPrivate()) && da) && isBetterBind(md, classBindmethods.get(md.getName()))) {
classBindmethods.put(md.getName(), md);
}
}
private boolean isBetter(MethodDef test, MethodDef existing, Set<String> allowedParams) {
int testRating = rateLifecycle(test, allowedParams);
if (existing == null)
// ignore invalid methods
return testRating < 6;
if (testRating < rateLifecycle(existing, allowedParams))
return true;
return false;
}
private boolean isBetterBind(MethodDef test, MethodDef existing) {
int testRating = rateBind(test);
if (existing == null)
// ignore invalid methods
return testRating < 6;
if (testRating < rateBind(existing))
return true;
return false;
}
});
lifecycleMethods.putAll(classLifecyclemethods);
bindmethods.putAll(classBindmethods);
typeRef = clazz.getSuper();
if (typeRef == null)
break;
clazz = analyzer.findClass(typeRef);
privateAllowed = false;
defaultAllowed = defaultAllowed && topPackage.equals(typeRef.getPackageRef().getFQN());
}
if (cd.activate != null && !lifecycleMethods.containsKey(cd.activate)) {
error("in component %s, activate method %s specified but not found", cd.implementation.getFQN(), cd.activate);
cd.activate = null;
}
if (cd.deactivate != null && !lifecycleMethods.containsKey(cd.deactivate)) {
error("in component %s, deactivate method %s specified but not found", cd.implementation.getFQN(), cd.deactivate);
cd.activate = null;
}
if (cd.modified != null && !lifecycleMethods.containsKey(cd.modified)) {
error("in component %s, modified method %s specified but not found", cd.implementation.getFQN(), cd.modified);
cd.activate = null;
}
provide(cd, provides, impl);
properties(cd, info, name);
reference(info, impl, cd, bindmethods);
// compute namespace after references, an updated method means ds 1.2.
getNamespace(info, cd, lifecycleMethods);
cd.prepare(analyzer);
return cd.getTag();
}
use of aQute.bnd.osgi.ClassDataCollector in project bnd by bndtools.
the class Target method testSimple.
public void testSimple() throws Exception {
Analyzer analyzer = new Analyzer();
Clazz clazz = new Clazz(analyzer, "", null);
ClassDataCollector cd = new ClassDataCollector() {
@Override
public void addReference(TypeRef token) {
}
@Override
public void annotation(Annotation annotation) {
System.err.println("Annotation " + annotation);
}
@Override
public void classBegin(int access, TypeRef name) {
System.err.println("Class " + name);
}
@Override
public void classEnd() {
System.err.println("Class end ");
}
@Override
public void extendsClass(TypeRef name) {
System.err.println("extends " + name);
}
@Override
public void implementsInterfaces(TypeRef[] name) {
System.err.println("implements " + Arrays.toString(name));
}
@Override
public void parameter(int p) {
System.err.println("parameter " + p);
}
};
clazz.parseClassFile(getClass().getResourceAsStream("Target.class"), cd);
}
Aggregations