use of org.infinispan.protostream.impl.parser.AnnotationParser in project protostream by infinispan.
the class AnnotatedDescriptorImpl method processAnnotations.
/**
* Extract annotations by parsing the documentation comment and run the configured {@link
* AnnotationMetadataCreator}s.
*
* @throws AnnotationParserException if annotation parsing fails
*/
private void processAnnotations() throws AnnotationParserException {
// we are lazily processing the annotations, if there is a documentation text attached to this element
if (annotations == null) {
if (documentation != null) {
AnnotationParser parser = new AnnotationParser(documentation, true);
List<AnnotationElement.Annotation> parsedAnnotations = parser.parse();
Map<String, AnnotationElement.Annotation> _annotations = new LinkedHashMap<>();
Map<String, AnnotationElement.Annotation> _containers = new LinkedHashMap<>();
for (AnnotationElement.Annotation annotation : parsedAnnotations) {
AnnotationConfiguration annotationConfig = getAnnotationConfig(annotation);
if (annotationConfig == null) {
// unknown annotations are ignored, but we might want to log a warning
if (getAnnotationsConfig().logUndefinedAnnotations()) {
log.warnf("Encountered and ignored and unknown annotation \"%s\" on %s", annotation.getName(), fullName);
}
} else {
validateAttributes(annotation, annotationConfig);
// convert single values to arrays if needed and set the default values for missing attributes
normalizeValues(annotation, annotationConfig);
if (_annotations.containsKey(annotation.getName()) || _containers.containsKey(annotation.getName())) {
// did we just find a repeatable annotation?
if (annotationConfig.repeatable() != null) {
AnnotationElement.Annotation container = _containers.get(annotation.getName());
if (container == null) {
List<AnnotationElement.Value> values = new LinkedList<>();
values.add(_annotations.remove(annotation.getName()));
values.add(annotation);
AnnotationElement.Attribute value = new AnnotationElement.Attribute(annotation.position, AnnotationElement.Annotation.VALUE_DEFAULT_ATTRIBUTE, new AnnotationElement.Array(annotation.position, values));
container = new AnnotationElement.Annotation(annotation.position, annotationConfig.repeatable(), Collections.singletonMap(value.getName(), value));
_containers.put(annotation.getName(), container);
_annotations.put(container.getName(), container);
} else {
AnnotationElement.Array value = (AnnotationElement.Array) container.getAttributeValue(AnnotationElement.Annotation.VALUE_DEFAULT_ATTRIBUTE);
value.getValues().add(annotation);
}
} else {
// it's just a duplicate, not a proper 'repeated' annotation
throw new AnnotationParserException(String.format("Error: %s: duplicate annotation definition \"%s\" on %s", AnnotationElement.positionToString(annotation.position), annotation.getName(), fullName));
}
} else {
_annotations.put(annotation.getName(), annotation);
}
}
}
// annotations are now completely parsed and validated
annotations = _annotations.isEmpty() ? Collections.emptyMap() : Collections.unmodifiableMap(_annotations);
// create metadata based on the annotations
processedAnnotations = new LinkedHashMap<>();
for (AnnotationElement.Annotation annotation : annotations.values()) {
AnnotationConfiguration annotationConfig = getAnnotationConfig(annotation);
AnnotationMetadataCreator<Object, AnnotatedDescriptor> creator = (AnnotationMetadataCreator<Object, AnnotatedDescriptor>) annotationConfig.metadataCreator();
if (creator != null) {
Object metadataForAnnotation;
try {
metadataForAnnotation = creator.create(this, annotation);
} catch (Exception ex) {
log.errorf(ex, "Exception encountered while processing annotation \"%s\" on %s", annotation.getName(), fullName);
throw ex;
}
processedAnnotations.put(annotation.getName(), metadataForAnnotation);
}
}
} else {
annotations = Collections.emptyMap();
processedAnnotations = Collections.emptyMap();
}
}
}
Aggregations