Annotation[] classAnnotations = managedClass.getAnnotations();
// per 'getAnnotations' docs, array is returned by copy, so we can modify it...
Arrays.sort(classAnnotations, typeAnnotationsSorter);
JpaClassDescriptor descriptor = new JpaClassDescriptor(managedClass);
// initially set access to the map level access - may be overriden below
descriptor.setAccess(context.getEntityMap().getAccess());
AnnotationContext stack = new AnnotationContext(descriptor);
stack.push(context.getEntityMap());
// === push class-level stuff
for (int i = 0; i < classAnnotations.length; i++) {
AnnotationProcessor processor = classProcessorFactory
.getProcessor(classAnnotations[i]);
if (processor != null) {
processor.onStartElement(managedClass, stack);
}
}
// if class is not properly annotated, bail early
if (stack.depth() == 1) {
return;
}
// apply entity callbacks ...
if (stack.peek() instanceof JpaAbstractEntity) {
for (Method callback : getEntityCallbacks(managedClass)) {
applyEntityCallbackAnnotations(callback, stack);
}
}
// per JPA spec, 2.1.1, regarding access type:
// When annotations are used, the placement of the mapping annotations on either
// the persistent fields or persistent properties of the entity class specifies
// the access type as being either field- or property-based access respectively.
// Question (andrus) - if no annotations are placed at the field or method level,
// we still must determine the access type to apply default mappping rules. How?
// (using FIELD access for now).
boolean fieldAccess = false;
for (JpaPropertyDescriptor property : descriptor.getFieldDescriptors()) {
stack.setPropertyDescriptor(property);
if (applyMemberAnnotations(property, stack)) {
fieldAccess = true;
}
}
boolean propertyAccess = false;
for (JpaPropertyDescriptor property : descriptor.getPropertyDescriptors()) {
stack.setPropertyDescriptor(property);
if (applyMemberAnnotations(property, stack)) {
propertyAccess = true;
}
}
if (stack.peek() instanceof JpaManagedClass) {
JpaManagedClass entity = (JpaManagedClass) stack.peek();
// sanity check
if (fieldAccess && propertyAccess) {
throw new JpaProviderException("Entity '"
+ entity.getClassName()
+ "' has both property and field annotations.");
}
// TODO: andrus - 11/29/2006 - clean this redundancy - access field should be
// stored either in the entity or the descriptor.
if (fieldAccess) {
descriptor.setAccess(AccessType.FIELD);
entity.setAccess(AccessType.FIELD);
}
else if (propertyAccess) {
descriptor.setAccess(AccessType.PROPERTY);
entity.setAccess(AccessType.PROPERTY);
}
}
// === pop class-level stuff