use of aQute.bnd.component.error.DeclarativeServicesAnnotationError in project bnd by bndtools.
the class AnnotationReader method doActivate.
/**
*
*/
protected void doActivate() {
String methodDescriptor = member.getDescriptor().toString();
DeclarativeServicesAnnotationError details = new DeclarativeServicesAnnotationError(className.getFQN(), member.getName(), methodDescriptor, ErrorType.ACTIVATE_SIGNATURE_ERROR);
if (!(member instanceof MethodDef)) {
analyzer.error("Activate annotation on a field %s.%s", clazz, member.getDescriptor()).details(details);
return;
}
boolean hasMapReturnType = false;
Matcher m = LIFECYCLEDESCRIPTORDS10.matcher(methodDescriptor);
if ("activate".equals(member.getName()) && m.matches()) {
component.activate = member.getName();
hasMapReturnType = m.group(3) != null;
if (!member.isProtected())
component.updateVersion(V1_1);
} else {
m = LIFECYCLEDESCRIPTORDS11.matcher(methodDescriptor);
if (m.matches()) {
component.activate = member.getName();
component.updateVersion(V1_1);
hasMapReturnType = m.group(6) != null;
} else {
m = LIFECYCLEDESCRIPTORDS13.matcher(methodDescriptor);
if (m.matches()) {
component.activate = member.getName();
component.updateVersion(V1_3);
hasMapReturnType = m.group(4) != null;
processAnnotationArguments(methodDescriptor, details);
} else
analyzer.error("Activate method for %s descriptor %s is not acceptable.", clazz, member.getDescriptor()).details(details);
}
}
checkMapReturnType(hasMapReturnType, details);
}
use of aQute.bnd.component.error.DeclarativeServicesAnnotationError in project bnd by bndtools.
the class ComponentAnnotationReader method annotation.
@Override
public void annotation(Annotation annotation) {
String fqn = annotation.getName().getFQN();
if (fqn.equals("aQute.bnd.annotation.component.Component")) {
if (!mismatchedAnnotations.isEmpty()) {
String componentName = annotation.get(Component.NAME);
componentName = (componentName == null) ? className.getFQN() : componentName;
for (Entry<String, List<DeclarativeServicesAnnotationError>> e : mismatchedAnnotations.entrySet()) {
for (DeclarativeServicesAnnotationError errorDetails : e.getValue()) {
if (errorDetails.fieldName != null) {
reporter.error("The DS component %s uses bnd annotations to declare it as a component, but also uses the standard DS annotation: %s on field %s. It is an error to mix these two types of annotations", componentName, e.getKey(), errorDetails.fieldName).details(errorDetails);
} else if (errorDetails.methodName != null) {
reporter.error("The DS component %s uses bnd annotations to declare it as a component, but also uses the standard DS annotation: %s on method %s with signature %s. It is an error to mix these two types of annotations", componentName, e.getKey(), errorDetails.methodName, errorDetails.methodSignature).details(errorDetails);
} else {
reporter.error("The DS component %s uses bnd annotations to declare it as a component, but also uses the standard DS annotation: %s. It is an error to mix these two types of annotations", componentName, e.getKey()).details(errorDetails);
}
}
}
return;
}
set(COMPONENT_NAME, annotation.get(Component.NAME), "<>");
set(COMPONENT_FACTORY, annotation.get(Component.FACTORY), false);
setBoolean(COMPONENT_ENABLED, annotation.get(Component.ENABLED), true);
setBoolean(COMPONENT_IMMEDIATE, annotation.get(Component.IMMEDIATE), false);
setBoolean(COMPONENT_SERVICEFACTORY, annotation.get(Component.SERVICEFACTORY), false);
if (annotation.get(Component.DESIGNATE) != null) {
TypeRef configs = annotation.get(Component.DESIGNATE);
if (configs != null) {
set(COMPONENT_DESIGNATE, configs.getFQN(), "");
}
}
if (annotation.get(Component.DESIGNATE_FACTORY) != null) {
TypeRef configs = annotation.get(Component.DESIGNATE_FACTORY);
if (configs != null) {
set(COMPONENT_DESIGNATEFACTORY, configs.getFQN(), "");
}
}
setVersion((String) annotation.get(Component.VERSION));
String configurationPolicy = annotation.get(Component.CONFIGURATION_POLICY);
if (configurationPolicy != null)
set(COMPONENT_CONFIGURATION_POLICY, configurationPolicy.toLowerCase(), "");
doProperties(annotation);
Object[] provides = (Object[]) annotation.get(Component.PROVIDE);
String[] p;
if (provides == null) {
// fqn.
if (interfaces != null) {
List<String> result = new ArrayList<String>();
for (int i = 0; i < interfaces.length; i++) {
if (!interfaces[i].getBinary().equals("scala/ScalaObject"))
result.add(interfaces[i].getFQN());
}
p = result.toArray(EMPTY);
} else
p = EMPTY;
} else {
// We have explicit interfaces set
p = new String[provides.length];
for (int i = 0; i < provides.length; i++) {
p[i] = ((TypeRef) provides[i]).getFQN();
}
}
if (p.length > 0) {
set(COMPONENT_PROVIDE, Processor.join(Arrays.asList(p)), "<>");
}
} else if (fqn.equals("aQute.bnd.annotation.component.Activate")) {
if (!checkMethod())
setVersion(V1_1);
if (!ACTIVATEDESCRIPTOR.matcher(method.getDescriptor().toString()).matches())
reporter.error("Activate method for %s does not have an acceptable prototype, only Map, ComponentContext, or BundleContext is allowed. Found: %s", className, method.getDescriptor()).details(new DeclarativeServicesAnnotationError(className.getFQN(), method.getName(), method.getDescriptor().toString(), ErrorType.ACTIVATE_SIGNATURE_ERROR));
if (method.getName().equals("activate") && OLDACTIVATEDESCRIPTOR.matcher(method.getDescriptor().toString()).matches()) {
// this is the default!
} else {
setVersion(V1_1);
set(COMPONENT_ACTIVATE, method, "<>");
}
} else if (fqn.equals("aQute.bnd.annotation.component.Deactivate")) {
if (!checkMethod())
setVersion(V1_1);
if (!ACTIVATEDESCRIPTOR.matcher(method.getDescriptor().toString()).matches())
reporter.error("Deactivate method for %s does not have an acceptable prototype, only Map, ComponentContext, or BundleContext is allowed. Found: %s", className, method.getDescriptor()).details(new DeclarativeServicesAnnotationError(className.getFQN(), method.getName(), method.getDescriptor().toString(), ErrorType.DEACTIVATE_SIGNATURE_ERROR));
if (method.getName().equals("deactivate") && OLDACTIVATEDESCRIPTOR.matcher(method.getDescriptor().toString()).matches()) {
// This is the default!
} else {
setVersion(V1_1);
set(COMPONENT_DEACTIVATE, method, "<>");
}
} else if (fqn.equals("aQute.bnd.annotation.component.Modified")) {
if (!ACTIVATEDESCRIPTOR.matcher(method.getDescriptor().toString()).matches())
reporter.error("Modified method for %s does not have an acceptable prototype, only Map, ComponentContext, or BundleContext is allowed. Found: %s", className, method.getDescriptor()).details(new DeclarativeServicesAnnotationError(className.getFQN(), method.getName(), method.getDescriptor().toString(), ErrorType.MODIFIED_SIGNATURE_ERROR));
set(COMPONENT_MODIFIED, method, "<>");
setVersion(V1_1);
} else if (fqn.equals("aQute.bnd.annotation.component.Reference")) {
String name = (String) annotation.get("aQute.bnd.annotation.component.Reference");
String bind = method.getName();
String unbind = null;
if (name == null) {
Matcher m = BINDMETHOD.matcher(method.getName());
if (m.matches()) {
name = m.group(2).toLowerCase() + m.group(3);
} else {
name = method.getName().toLowerCase();
}
}
String simpleName = name;
unbind = annotation.get(Reference.UNBIND);
if (bind != null) {
name = name + "/" + bind;
if (unbind != null)
name = name + "/" + unbind;
}
String service = null;
TypeRef serviceTR = annotation.get(Reference.SERVICE);
if (serviceTR != null)
service = serviceTR.getFQN();
if (service == null) {
// We have to find the type of the current method to
// link it to the referenced service.
Matcher m = BINDDESCRIPTOR.matcher(method.getDescriptor().toString());
if (m.matches()) {
service = Descriptors.binaryToFQN(m.group(1));
} else
throw new IllegalArgumentException("Cannot detect the type of a Component Reference from the descriptor: " + method.getDescriptor());
}
// Check if we have a target, this must be a filter
String target = annotation.get(Reference.TARGET);
if (target != null) {
String error = Verifier.validateFilter(target);
if (error != null) {
reporter.error("Invalid target filter %s for %s: %s", target, name, error).details(new DeclarativeServicesAnnotationError(className.getFQN(), bind, method.getDescriptor().toString(), ErrorType.INVALID_TARGET_FILTER));
}
service = service + target;
}
Integer c = annotation.get(Reference.TYPE);
if (c != null && !c.equals(0) && !c.equals((int) '1')) {
service = service + (char) c.intValue();
}
if (map.containsKey(name))
reporter.error("In component %s, Multiple references with the same name: %s. Previous def: %s, this def: %s", name, map.get(name), service, "").details(new DeclarativeServicesAnnotationError(className.getFQN(), null, null, ErrorType.MULTIPLE_REFERENCES_SAME_NAME));
map.put(name, service);
if (isTrue(annotation.get(Reference.MULTIPLE)))
multiple.add(simpleName);
if (isTrue(annotation.get(Reference.OPTIONAL)))
optional.add(simpleName);
if (isTrue(annotation.get(Reference.DYNAMIC)))
dynamic.add(simpleName);
if (!checkMethod())
setVersion(V1_1);
else if (REFERENCEBINDDESCRIPTOR.matcher(method.getDescriptor().toString()).matches() || !OLDBINDDESCRIPTOR.matcher(method.getDescriptor().toString()).matches())
setVersion(V1_1);
} else if (fqn.startsWith("org.osgi.service.component.annotations")) {
DeclarativeServicesAnnotationError errorDetails;
switch(annotation.getElementType()) {
case METHOD:
errorDetails = new DeclarativeServicesAnnotationError(className.getFQN(), method.getName(), method.getDescriptor().toString(), ErrorType.MIXED_USE_OF_DS_ANNOTATIONS_BND);
break;
case FIELD:
errorDetails = new DeclarativeServicesAnnotationError(className.getFQN(), field.getName(), ErrorType.MIXED_USE_OF_DS_ANNOTATIONS_BND);
break;
default:
errorDetails = new DeclarativeServicesAnnotationError(className.getFQN(), null, ErrorType.MIXED_USE_OF_DS_ANNOTATIONS_BND);
}
List<DeclarativeServicesAnnotationError> errors = mismatchedAnnotations.get(fqn);
if (errors == null) {
errors = new ArrayList<DeclarativeServicesAnnotationError>();
mismatchedAnnotations.put(fqn, errors);
}
errors.add(errorDetails);
}
}
use of aQute.bnd.component.error.DeclarativeServicesAnnotationError in project bnd by bndtools.
the class AnnotationReader method doComponent.
/**
* @param annotation
* @throws Exception
*/
@SuppressWarnings("deprecation")
protected void doComponent(Component comp, Annotation annotation) throws Exception {
if (!mismatchedAnnotations.isEmpty()) {
String componentName = comp.name();
componentName = (componentName == null) ? className.getFQN() : componentName;
for (Entry<String, List<DeclarativeServicesAnnotationError>> e : mismatchedAnnotations.entrySet()) {
for (DeclarativeServicesAnnotationError errorDetails : e.getValue()) {
if (errorDetails.fieldName != null) {
analyzer.error("The DS component %s uses standard annotations to declare it as a component, but also uses the bnd DS annotation: %s on field %s. It is an error to mix these two types of annotations", componentName, e.getKey(), errorDetails.fieldName).details(errorDetails);
} else if (errorDetails.methodName != null) {
analyzer.error("The DS component %s uses standard annotations to declare it as a component, but also uses the bnd DS annotation: %s on method %s with signature %s. It is an error to mix these two types of annotations", componentName, e.getKey(), errorDetails.methodName, errorDetails.methodSignature).details(errorDetails);
} else {
analyzer.error("The DS component %s uses standard annotations to declare it as a component, but also uses the bnd DS annotation: %s. It is an error to mix these two types of annotations", componentName, e.getKey()).details(errorDetails);
}
}
}
return;
}
// Check if we are doing a super class
if (component.implementation != null)
return;
component.implementation = clazz.getClassName();
component.name = comp.name();
component.factory = comp.factory();
component.configurationPolicy = comp.configurationPolicy();
if (annotation.get("enabled") != null)
component.enabled = comp.enabled();
if (annotation.get("factory") != null)
component.factory = comp.factory();
if (annotation.get("immediate") != null)
component.immediate = comp.immediate();
if (annotation.get("servicefactory") != null)
component.scope = comp.servicefactory() ? ServiceScope.BUNDLE : ServiceScope.SINGLETON;
if (annotation.get("scope") != null && comp.scope() != ServiceScope.DEFAULT) {
component.scope = comp.scope();
if (comp.scope() == ServiceScope.PROTOTYPE) {
component.updateVersion(V1_3);
}
}
if (annotation.get("configurationPid") != null) {
component.configurationPid = comp.configurationPid();
if (component.configurationPid.length > 1) {
component.updateVersion(V1_3);
} else {
component.updateVersion(V1_2);
}
}
if (annotation.get("xmlns") != null)
component.xmlns = comp.xmlns();
String[] properties = comp.properties();
if (properties != null)
for (String entry : properties) {
if (entry.contains("=")) {
analyzer.error("Found an = sign in an OSGi DS Component annotation on %s. In the bnd annotation " + "this is an actual property but in the OSGi, this element must refer to a path with Java properties. " + "However, found a path with an '=' sign which looks like a mixup (%s) with the 'property' element.", clazz, entry).details(new DeclarativeServicesAnnotationError(className.getFQN(), null, null, ErrorType.COMPONENT_PROPERTIES_ERROR));
}
component.properties.add(entry);
}
doProperty(comp.property());
Object[] x = annotation.get("service");
if (x == null) {
// fqn.
if (interfaces != null) {
List<TypeRef> result = new ArrayList<TypeRef>();
for (int i = 0; i < interfaces.length; i++) {
if (!interfaces[i].equals(analyzer.getTypeRef("scala/ScalaObject")))
result.add(interfaces[i]);
}
component.service = result.toArray(EMPTY);
}
} else {
// We have explicit interfaces set
component.service = new TypeRef[x.length];
for (int i = 0; i < x.length; i++) {
TypeRef typeRef = (TypeRef) x[i];
Clazz service = analyzer.findClass(typeRef);
if (!analyzer.assignable(clazz, service)) {
analyzer.error("Class %s is not assignable to specified service %s", clazz.getFQN(), typeRef.getFQN()).details(new DeclarativeServicesAnnotationError(className.getFQN(), null, null, ErrorType.INCOMPATIBLE_SERVICE));
}
component.service[i] = typeRef;
}
}
// make sure reference processing knows this is a Reference in Component
member = null;
Object[] refAnnotations = annotation.get("reference");
if (refAnnotations != null) {
for (Object o : refAnnotations) {
Annotation refAnnotation = (Annotation) o;
Reference ref = refAnnotation.getAnnotation();
doReference(ref, refAnnotation);
}
}
}
use of aQute.bnd.component.error.DeclarativeServicesAnnotationError in project bnd by bndtools.
the class AnnotationReader method doModified.
/**
*
*/
protected void doModified() {
String methodDescriptor = member.getDescriptor().toString();
DeclarativeServicesAnnotationError details = new DeclarativeServicesAnnotationError(className.getFQN(), member.getName(), methodDescriptor, ErrorType.MODIFIED_SIGNATURE_ERROR);
if (!(member instanceof MethodDef)) {
analyzer.error("Modified annotation on a field %s.%s", clazz, member.getDescriptor()).details(details);
return;
}
boolean hasMapReturnType = false;
Matcher m = LIFECYCLEDESCRIPTORDS11.matcher(methodDescriptor);
if (m.matches()) {
component.modified = member.getName();
component.updateVersion(V1_1);
hasMapReturnType = m.group(6) != null;
} else {
m = LIFECYCLEDESCRIPTORDS13.matcher(methodDescriptor);
if (m.matches()) {
component.modified = member.getName();
component.updateVersion(V1_3);
hasMapReturnType = m.group(4) != null;
processAnnotationArguments(methodDescriptor, details);
} else
analyzer.error("Modified method for %s descriptor %s is not acceptable.", clazz, member.getDescriptor()).details(details);
}
checkMapReturnType(hasMapReturnType, details);
}
use of aQute.bnd.component.error.DeclarativeServicesAnnotationError in project bnd by bndtools.
the class HeaderReader method reference.
/**
* @param info
* @param impl TODO
* @param descriptors TODO
* @param pw
* @throws Exception
*/
void reference(Map<String, String> info, String impl, ComponentDef cd, Map<String, MethodDef> descriptors) throws Exception {
Collection<String> dynamic = new ArrayList<String>(split(info.get(COMPONENT_DYNAMIC)));
Collection<String> optional = new ArrayList<String>(split(info.get(COMPONENT_OPTIONAL)));
Collection<String> multiple = new ArrayList<String>(split(info.get(COMPONENT_MULTIPLE)));
Collection<String> greedy = new ArrayList<String>(split(info.get(COMPONENT_GREEDY)));
for (Map.Entry<String, String> entry : info.entrySet()) {
// Skip directives
String referenceName = entry.getKey();
if (referenceName.endsWith(":")) {
if (!SET_COMPONENT_DIRECTIVES.contains(referenceName))
error("Unrecognized directive in " + Constants.SERVICE_COMPONENT + " header: %s", referenceName);
continue;
}
// Parse the bind/unbind methods from the name
// if set. They are separated by '/'
String bind = null;
String unbind = null;
String updated = null;
boolean bindCalculated = true;
boolean unbindCalculated = true;
boolean updatedCalculated = true;
if (referenceName.indexOf('/') >= 0) {
String[] parts = referenceName.split("/");
referenceName = parts[0];
if (parts[1].length() > 0) {
bind = parts[1];
bindCalculated = false;
} else {
bind = calculateBind(referenceName);
}
bind = parts[1].length() == 0 ? calculateBind(referenceName) : parts[1];
if (parts.length > 2 && parts[2].length() > 0) {
unbind = parts[2];
unbindCalculated = false;
} else {
if (bind.startsWith("add"))
unbind = bind.replaceAll("add(.+)", "remove$1");
else
unbind = "un" + bind;
}
if (parts.length > 3) {
updated = parts[3];
updatedCalculated = false;
}
} else if (Character.isLowerCase(referenceName.charAt(0))) {
bind = calculateBind(referenceName);
unbind = "un" + bind;
updated = "updated" + Character.toUpperCase(referenceName.charAt(0)) + referenceName.substring(1);
}
String interfaceName = entry.getValue();
if (interfaceName == null || interfaceName.length() == 0) {
error("Invalid Interface Name for references in Service Component: %s=%s", referenceName, interfaceName);
continue;
}
// So why not check the methods
if (descriptors.size() > 0) {
// Verify that the bind method exists
if (!descriptors.containsKey(bind))
if (bindCalculated)
bind = null;
else
error("In component %s, the bind method %s for %s not defined", cd.effectiveName(), bind, referenceName);
// Check if the unbind method exists
if (!descriptors.containsKey(unbind)) {
if (unbindCalculated)
// remove it
unbind = null;
else
error("In component %s, the unbind method %s for %s not defined", cd.effectiveName(), unbind, referenceName);
}
if (!descriptors.containsKey(updated)) {
if (updatedCalculated)
// remove it
updated = null;
else
error("In component %s, the updated method %s for %s is not defined", cd.effectiveName(), updated, referenceName);
}
}
// Check the cardinality by looking at the last
// character of the value
char c = interfaceName.charAt(interfaceName.length() - 1);
if ("?+*~".indexOf(c) >= 0) {
if (c == '?' || c == '*' || c == '~')
optional.add(referenceName);
if (c == '+' || c == '*')
multiple.add(referenceName);
if (c == '+' || c == '*' || c == '?')
dynamic.add(referenceName);
interfaceName = interfaceName.substring(0, interfaceName.length() - 1);
}
// Parse the target from the interface name
// The target is a filter.
String target = null;
Matcher m = REFERENCE.matcher(interfaceName);
if (m.matches()) {
interfaceName = m.group(1);
target = m.group(2);
}
TypeRef ref = analyzer.getTypeRefFromFQN(interfaceName);
analyzer.referTo(ref);
ReferenceDef rd = new ReferenceDef(null);
rd.name = referenceName;
rd.service = interfaceName;
if (optional.contains(referenceName)) {
if (multiple.contains(referenceName)) {
rd.cardinality = ReferenceCardinality.MULTIPLE;
} else {
rd.cardinality = ReferenceCardinality.OPTIONAL;
}
} else {
if (multiple.contains(referenceName)) {
rd.cardinality = ReferenceCardinality.AT_LEAST_ONE;
} else {
rd.cardinality = ReferenceCardinality.MANDATORY;
}
}
if (bind != null) {
rd.bind = bind;
if (unbind != null) {
rd.unbind = unbind;
}
if (updated != null) {
rd.updated = updated;
}
}
if (dynamic.contains(referenceName)) {
rd.policy = ReferencePolicy.DYNAMIC;
if (rd.unbind == null)
error("In component %s, reference %s is dynamic but has no unbind method.", cd.effectiveName(), rd.name).details(new DeclarativeServicesAnnotationError(cd.implementation.getFQN(), null, null, ErrorType.DYNAMIC_REFERENCE_WITHOUT_UNBIND));
}
if (greedy.contains(referenceName)) {
rd.policyOption = ReferencePolicyOption.GREEDY;
}
if (target != null) {
rd.target = target;
}
cd.references.put(referenceName, rd);
}
}
Aggregations