use of aQute.bnd.osgi.Clazz in project bnd by bndtools.
the class MetaTypeReader method parseAndMergeInheritedMetadata.
private void parseAndMergeInheritedMetadata(TypeRef ref, Clazz child) throws Exception {
if (ref.isJava())
return;
Clazz ec = reporter.findClass(ref);
if (ec == null) {
reporter.error("Missing inherited class for Metatype annotations: %s from %s", ref, child.getClassName());
} else {
@SuppressWarnings("resource") MetaTypeReader mtr = new MetaTypeReader(ec, reporter);
mtr.setDesignate(designatePid, factory);
mtr.finish();
for (Map.Entry<MethodDef, Meta.AD> entry : mtr.methods.entrySet()) addMethod(entry.getKey(), entry.getValue());
handleInheritedClasses(ec);
}
}
use of aQute.bnd.osgi.Clazz in project bnd by bndtools.
the class MetaTypeReader method addMethod.
private void addMethod(MethodDef method, Meta.AD ad) throws Exception {
if (method.isStatic())
return;
// Set all the defaults.
String rtype = method.getGenericReturnType();
String id = Configurable.mangleMethodName(method.getName());
String name = Clazz.unCamel(id);
int cardinality = 0;
if (rtype.endsWith("[]")) {
cardinality = Integer.MAX_VALUE;
rtype = rtype.substring(0, rtype.length() - 2);
}
if (rtype.indexOf('<') > 0) {
if (cardinality != 0)
reporter.error("AD for %s.%s uses an array of collections in return type (%s), Metatype allows either Vector or array", clazz.getClassName().getFQN(), method.getName(), method.getType().getFQN());
Matcher m = COLLECTION.matcher(rtype);
if (m.matches()) {
rtype = Clazz.objectDescriptorToFQN(m.group(3));
cardinality = Integer.MIN_VALUE;
}
}
Meta.Type type = getType(rtype);
boolean required = ad == null || ad.required();
String deflt = null;
String max = null;
String min = null;
String[] optionLabels = null;
String[] optionValues = null;
String description = null;
TypeRef typeRef = reporter.getTypeRefFromFQN(rtype);
Clazz c = reporter.findClass(typeRef);
if (c != null && c.isEnum()) {
optionValues = parseOptionValues(c);
}
if (ad != null) {
if (ad.id() != null)
id = ad.id();
if (ad.name() != null)
name = ad.name();
if (ad.cardinality() != 0)
cardinality = ad.cardinality();
if (ad.type() != null)
type = ad.type();
if (ad.description() != null)
description = ad.description();
if (ad.optionLabels() != null)
optionLabels = ad.optionLabels();
if (ad.optionValues() != null)
optionValues = ad.optionValues();
if (ad.min() != null)
min = ad.min();
if (ad.max() != null)
max = ad.max();
if (ad.deflt() != null)
deflt = ad.deflt();
}
if (optionValues != null) {
if (optionLabels == null || optionLabels.length == 0) {
optionLabels = new String[optionValues.length];
for (int i = 0; i < optionValues.length; i++) optionLabels[i] = Clazz.unCamel(optionValues[i]);
}
if (optionLabels.length != optionValues.length) {
reporter.error("Option labels and option values not the same length for %s", id);
optionLabels = optionValues;
}
}
Tag adt = new Tag(this.ocd, "AD");
adt.addAttribute("name", name);
adt.addAttribute("id", id);
adt.addAttribute("cardinality", cardinality);
adt.addAttribute("required", required);
adt.addAttribute("default", deflt);
adt.addAttribute("type", type);
adt.addAttribute("max", max);
adt.addAttribute("min", min);
adt.addAttribute("description", description);
if (optionLabels != null && optionValues != null) {
for (int i = 0; i < optionLabels.length; i++) {
Tag option = new Tag(adt, "Option");
option.addAttribute("label", optionLabels[i]);
option.addAttribute("value", optionValues[i]);
}
}
}
use of aQute.bnd.osgi.Clazz in project bnd by bndtools.
the class DSAnnotations method analyzeJar.
public boolean analyzeJar(Analyzer analyzer) throws Exception {
Parameters header = OSGiHeader.parseHeader(analyzer.getProperty(Constants.DSANNOTATIONS, "*"));
if (header.size() == 0)
return false;
minVersion = AnnotationReader.V1_3;
Parameters optionsHeader = OSGiHeader.parseHeader(analyzer.mergeProperties(Constants.DSANNOTATIONS_OPTIONS));
EnumSet<Options> options = EnumSet.noneOf(Options.class);
for (Map.Entry<String, Attrs> entry : optionsHeader.entrySet()) {
try {
Options.parseOption(entry, options, this);
} catch (IllegalArgumentException e) {
analyzer.error("Unrecognized %s value %s with attributes %s, expected values are %s", Constants.DSANNOTATIONS_OPTIONS, entry.getKey(), entry.getValue(), EnumSet.allOf(Options.class));
}
}
// obsolete but backwards compatible, use the options instead
if (Processor.isTrue(analyzer.getProperty("-dsannotations-inherit")))
options.add(Options.inherit);
if (Processor.isTrue(analyzer.getProperty("-ds-felix-extensions")))
options.add(Options.felixExtensions);
Instructions instructions = new Instructions(header);
Collection<Clazz> list = analyzer.getClassspace().values();
String sc = analyzer.getProperty(Constants.SERVICE_COMPONENT);
List<String> names = new ArrayList<String>();
if (sc != null && sc.trim().length() > 0)
names.add(sc);
TreeSet<String> provides = new TreeSet<String>();
TreeSet<String> requires = new TreeSet<String>();
Version maxVersion = AnnotationReader.V1_0;
XMLAttributeFinder finder = new XMLAttributeFinder(analyzer);
boolean componentProcessed = false;
for (Clazz c : list) {
for (Instruction instruction : instructions.keySet()) {
if (instruction.matches(c.getFQN())) {
if (instruction.isNegated())
break;
ComponentDef definition = AnnotationReader.getDefinition(c, analyzer, options, finder, minVersion);
if (definition != null) {
componentProcessed = true;
definition.sortReferences();
definition.prepare(analyzer);
String name = "OSGI-INF/" + analyzer.validResourcePath(definition.name, "Invalid component name") + ".xml";
names.add(name);
analyzer.getJar().putResource(name, new TagResource(definition.getTag()));
if (definition.service != null && !options.contains(Options.nocapabilities)) {
String[] objectClass = new String[definition.service.length];
for (int i = 0; i < definition.service.length; i++) {
Descriptors.TypeRef tr = definition.service[i];
objectClass[i] = tr.getFQN();
}
Arrays.sort(objectClass);
addServiceCapability(objectClass, provides);
}
if (!options.contains(Options.norequirements)) {
MergedRequirement serviceReqMerge = new MergedRequirement("osgi.service");
for (ReferenceDef ref : definition.references.values()) {
addServiceRequirement(ref, serviceReqMerge);
}
requires.addAll(serviceReqMerge.toStringList());
}
maxVersion = ComponentDef.max(maxVersion, definition.version);
}
}
}
}
if (componentProcessed && (options.contains(Options.extender) || (maxVersion.compareTo(AnnotationReader.V1_3) >= 0))) {
maxVersion = ComponentDef.max(maxVersion, AnnotationReader.V1_3);
addExtenderRequirement(requires, maxVersion);
}
sc = Processor.append(names.toArray(new String[0]));
analyzer.setProperty(Constants.SERVICE_COMPONENT, sc);
updateHeader(analyzer, Constants.REQUIRE_CAPABILITY, requires);
updateHeader(analyzer, Constants.PROVIDE_CAPABILITY, provides);
return false;
}
use of aQute.bnd.osgi.Clazz 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.Clazz in project bnd by bndtools.
the class XMLAttributeFinder method getXMLAttribute.
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;
}
Aggregations