&& !_cls.isAnnotationPresent(Embeddable.class)
&& !_cls.isAnnotationPresent(MappedSuperclass.class))
return null;
// find / create metadata
ClassMetaData meta = getMetaData();
if (meta == null)
return null;
Entity entity = (Entity) _cls.getAnnotation(Entity.class);
if (isMetaDataMode()) {
// while the spec only provides for embedded exclusive, it doesn't
// seem hard to support otherwise
if (entity == null)
meta.setEmbeddedOnly(true);
else {
meta.setEmbeddedOnly(false);
if (!StringUtils.isEmpty(entity.name()))
meta.setTypeAlias(entity.name());
}
}
// track fetch groups to parse them after fields, since they
// rely on field metadata
FetchGroup[] fgs = null;
DetachedState detached = null;
// track listeners since we need to merge them with entity callbacks
Collection<LifecycleCallbacks>[] listeners = null;
MetaDataTag tag;
for (Annotation anno : _cls.getDeclaredAnnotations()) {
tag = _tags.get(anno.annotationType());
if (tag == null) {
handleUnknownClassAnnotation(meta, anno);
continue;
}
switch (tag) {
case ENTITY_LISTENERS:
if (isMetaDataMode())
listeners = parseEntityListeners(meta,
(EntityListeners) anno);
break;
case EXCLUDE_DEFAULT_LISTENERS:
if (isMetaDataMode())
meta.getLifecycleMetaData()
.setIgnoreSystemListeners(true);
break;
case EXCLUDE_SUPERCLASS_LISTENERS:
if (isMetaDataMode())
meta.getLifecycleMetaData().setIgnoreSuperclassCallbacks
(LifecycleMetaData.IGNORE_HIGH);
break;
case FLUSH_MODE:
if (isMetaDataMode())
warnFlushMode(meta);
break;
case ID_CLASS:
if (isMetaDataMode())
meta.setObjectIdType(((IdClass) anno).value(), true);
break;
case NATIVE_QUERIES:
if (isQueryMode())
parseNamedNativeQueries(_cls,
((NamedNativeQueries) anno).value());
break;
case NATIVE_QUERY:
if (isQueryMode())
parseNamedNativeQueries(_cls, (NamedNativeQuery) anno);
break;
case QUERIES:
if (isQueryMode())
parseNamedQueries(_cls, ((NamedQueries) anno).value());
break;
case QUERY:
if (isQueryMode())
parseNamedQueries(_cls, (NamedQuery) anno);
break;
case SEQ_GENERATOR:
if (isMappingOverrideMode())
parseSequenceGenerator(_cls, (SequenceGenerator) anno);
break;
case DATA_CACHE:
if (isMetaDataMode())
parseDataCache(meta, (DataCache) anno);
break;
case DATASTORE_ID:
if (isMetaDataMode())
parseDataStoreId(meta, (DataStoreId) anno);
break;
case DETACHED_STATE:
detached = (DetachedState) anno;
break;
case FETCH_GROUP:
if (isMetaDataMode())
fgs = new FetchGroup[]{ (FetchGroup) anno };
break;
case FETCH_GROUPS:
if (isMetaDataMode())
fgs = ((FetchGroups) anno).value();
break;
default:
throw new UnsupportedException(_loc.get("unsupported", _cls,
anno.toString()));
}
}
if (isMetaDataMode()) {
parseDetachedState(meta, detached);
// merge callback methods with declared listeners
int[] highs = null;
if (listeners != null) {
highs = new int[listeners.length];
for (int i = 0; i < listeners.length; i++)
if (listeners[i] != null)
highs[i] = listeners[i].size();
}
recordCallbacks(meta, parseCallbackMethods(_cls, listeners, false,
false, getRepository()), highs, false);
// scan possibly non-PC hierarchy for callbacks.
// redundant for PC superclass but we don't know that yet
// so let LifecycleMetaData determine that
if (!Object.class.equals(_cls.getSuperclass())) {
recordCallbacks(meta, parseCallbackMethods(_cls.getSuperclass(),
null, true, false, getRepository()), null, true);
}
}
for (FieldMetaData fmd : meta.getDeclaredFields())
if (fmd.getManagement() == FieldMetaData.MANAGE_PERSISTENT)
parseMemberAnnotations(fmd);
// parse fetch groups after fields
if (fgs != null)
parseFetchGroups(meta, fgs);
// always parse mapping after metadata in case there are dependencies
if (isMappingOverrideMode()) {
parseClassMappingAnnotations(meta);
for (FieldMetaData fmd : meta.getDeclaredFields())
if (fmd.getManagement() == FieldMetaData.MANAGE_PERSISTENT)
parseMemberMappingAnnotations(fmd);
}
return meta;
}