use of aQute.bnd.osgi.Clazz.FieldDef in project bnd by bndtools.
the class AnnotationReader method doReference.
/**
* @param reference @Reference proxy backed by raw.
* @param raw @Reference contents
* @throws Exception
*/
protected void doReference(Reference reference, Annotation raw) throws Exception {
ReferenceDef def;
if (member == null)
def = new ReferenceDef(finder);
else if (referencesByMember.containsKey(member))
def = referencesByMember.get(member);
else {
def = new ReferenceDef(finder);
referencesByMember.put(member, def);
}
def.className = className.getFQN();
def.name = reference.name();
def.bind = reference.bind();
def.unbind = reference.unbind();
def.updated = reference.updated();
def.field = reference.field();
def.fieldOption = reference.fieldOption();
def.cardinality = reference.cardinality();
def.policy = reference.policy();
def.policyOption = reference.policyOption();
def.scope = reference.scope();
// Check if we have a target, this must be a filter
def.target = reference.target();
DeclarativeServicesAnnotationError details = getDetails(def, ErrorType.REFERENCE);
if (def.target != null) {
String error = Verifier.validateFilter(def.target);
if (error != null)
analyzer.error("Invalid target filter %s for %s: %s", def.target, def.name, error).details(getDetails(def, ErrorType.INVALID_TARGET_FILTER));
}
String annoService = null;
TypeRef annoServiceTR = raw.get("service");
if (annoServiceTR != null)
annoService = annoServiceTR.getFQN();
if (member != null) {
if (member instanceof MethodDef) {
def.bindDescriptor = member.getDescriptor().toString();
if (!member.isProtected())
def.updateVersion(V1_1);
def.bind = member.getName();
if (def.name == null) {
Matcher m = BINDNAME.matcher(member.getName());
if (m.matches())
def.name = m.group(2);
else
analyzer.error("Invalid name for bind method %s", member.getName()).details(getDetails(def, ErrorType.INVALID_REFERENCE_BIND_METHOD_NAME));
}
def.service = determineReferenceType(def.bindDescriptor, def, annoService, member.getSignature());
if (def.service == null)
analyzer.error("In component %s, method %s, cannot recognize the signature of the descriptor: %s", component.effectiveName(), def.name, member.getDescriptor());
} else if (member instanceof FieldDef) {
def.updateVersion(V1_3);
def.field = member.getName();
if (def.name == null)
def.name = def.field;
if (def.policy == null && member.isVolatile())
def.policy = ReferencePolicy.DYNAMIC;
String sig = member.getSignature();
if (sig == null)
// no generics, the descriptor will be the class name.
sig = member.getDescriptor().toString();
String[] sigs = sig.split("[<;>]");
int sigLength = sigs.length;
int index = 0;
boolean isCollection = false;
if ("Ljava/util/Collection".equals(sigs[index]) || "Ljava/util/List".equals(sigs[index])) {
index++;
isCollection = true;
}
// Along with determining the FieldCollectionType, the following
// code positions index to read the service type.
FieldCollectionType fieldCollectionType = null;
if (sufficientGenerics(index, sigLength, def, sig)) {
if ("Lorg/osgi/framework/ServiceReference".equals(sigs[index])) {
if (sufficientGenerics(index++, sigLength, def, sig)) {
fieldCollectionType = FieldCollectionType.reference;
}
} else if ("Lorg/osgi/service/component/ComponentServiceObjects".equals(sigs[index])) {
if (sufficientGenerics(index++, sigLength, def, sig)) {
fieldCollectionType = FieldCollectionType.serviceobjects;
}
} else if ("Ljava/util/Map".equals(sigs[index])) {
if (sufficientGenerics(index++, sigLength, def, sig)) {
fieldCollectionType = FieldCollectionType.properties;
}
} else if ("Ljava/util/Map$Entry".equals(sigs[index]) && sufficientGenerics(index++ + 5, sigLength, def, sig)) {
if ("Ljava/util/Map".equals(sigs[index++]) && "Ljava/lang/String".equals(sigs[index++])) {
if ("Ljava/lang/Object".equals(sigs[index]) || "+Ljava/lang/Object".equals(sigs[index])) {
fieldCollectionType = FieldCollectionType.tuple;
// ;>;
index += 3;
} else if ("*".equals(sigs[index])) {
fieldCollectionType = FieldCollectionType.tuple;
// >;
index += 2;
} else {
// no idea what service might
index = sigLength;
// be.
}
}
} else {
fieldCollectionType = FieldCollectionType.service;
}
}
if (isCollection) {
if (def.cardinality == null)
def.cardinality = ReferenceCardinality.MULTIPLE;
def.fieldCollectionType = fieldCollectionType;
}
if (def.policy == ReferencePolicy.DYNAMIC && (def.cardinality == ReferenceCardinality.MULTIPLE || def.cardinality == ReferenceCardinality.AT_LEAST_ONE) && member.isFinal()) {
if (def.fieldOption == FieldOption.REPLACE)
analyzer.error("In component %s, collection type field: %s is final and dynamic but marked with 'replace' fieldOption. Changing this to 'update'.", className, def.field).details(getDetails(def, ErrorType.DYNAMIC_FINAL_FIELD_WITH_REPLACE));
def.fieldOption = FieldOption.UPDATE;
}
if (annoService == null && index < sigs.length) {
annoService = sigs[index].substring(1).replace('/', '.');
}
def.service = annoService;
if (def.service == null)
analyzer.error("In component %s, method %s, cannot recognize the signature of the descriptor: %s", component.effectiveName(), def.name, member.getDescriptor()).details(details);
}
// end field
} else {
// not a member
def.service = annoService;
if (def.name == null) {
analyzer.error("Name must be supplied for a @Reference specified in the @Component annotation. Service: %s", def.service).details(getDetails(def, ErrorType.MISSING_REFERENCE_NAME));
return;
}
}
if (component.references.containsKey(def.name))
analyzer.error("In component %s, multiple references with the same name: %s. Previous def: %s, this def: %s", className, component.references.get(def.name), def.service, "").details(getDetails(def, ErrorType.MULTIPLE_REFERENCES_SAME_NAME));
else
component.references.put(def.name, def);
}
Aggregations