private ClassMetaData parseClassAnnotations()

in openjpa-persistence/src/main/java/org/apache/openjpa/persistence/AnnotationPersistenceMetaDataParser.java [548:733]


    private ClassMetaData parseClassAnnotations() {
        // Check to see if there is cached metadata for the class that we are currently parsing. It
        // is possible that one of the annotations (Entity, Embeddable, MappedSuperclass) is in the
        // orm.xml. We still need to look at these files for other annotations and more importantly
        // setup defaults (ie: Basic fields).
        ClassMetaData m = getRepository().getCachedMetaData(_cls);
        if (m == null) {
            if (!AccessController.doPrivileged(J2DoPrivHelper.isAnnotationPresentAction(_cls, Entity.class))
                && !AccessController.doPrivileged(J2DoPrivHelper.isAnnotationPresentAction(_cls, Embeddable.class))
                && !AccessController.doPrivileged(J2DoPrivHelper.isAnnotationPresentAction(_cls,
                    MappedSuperclass.class)))
                return null;
        }
        // find / create metadata
        ClassMetaData meta = (m == null) ? getMetaData() : m;
        if (meta == null)
            return null;

        Entity entity = _cls.getAnnotation(Entity.class);
        MappedSuperclass mapped = _cls.getAnnotation(MappedSuperclass.class);
        Embeddable embeddable = _cls.getAnnotation(Embeddable.class);
        if (isMetaDataMode()) {
            meta.setAbstract(mapped != null);
            if (embeddable != null) meta.setEmbeddable();
            // 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 (!StringUtil.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()) {
                    	Class<?> idClass = ((IdClass)anno).value();
                    	if (!Serializable.class.isAssignableFrom(idClass)) {
                    		_log.warn(_loc.get("id-class-not-serializable", idClass, _cls).toString());
                    	}
                        meta.setObjectIdType(((IdClass) anno).value(), true);
                    }
                    break;
                case NATIVE_QUERIES:
                    if (isQueryMode() && (meta.getSourceMode() & MODE_QUERY)==0)
                        parseNamedNativeQueries(_cls,
                            ((NamedNativeQueries) anno).value());
                    break;
                case NATIVE_QUERY:
                    if (isQueryMode() && (meta.getSourceMode() & MODE_QUERY)==0)
                        parseNamedNativeQueries(_cls, (NamedNativeQuery) anno);
                    break;
                case QUERIES:
                    if (isQueryMode() && (meta.getSourceMode() & MODE_QUERY)==0)
                        parseNamedQueries(_cls, ((NamedQueries) anno).value());
                    break;
                case QUERY:
                    if (isQueryMode() && (meta.getSourceMode() & MODE_QUERY)==0)
                        parseNamedQueries(_cls, (NamedQuery) anno);
                    break;
                case STOREDPROCEDURE_QUERIES:
                    if (isQueryMode())
                        parseNamedStoredProcedureQueries(_cls, ((NamedStoredProcedureQueries) anno).value());
                    break;
                case STOREDPROCEDURE_QUERY:
                    if (isQueryMode())
                        parseNamedStoredProcedureQueries(_cls, ((NamedStoredProcedureQuery) 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;
                case MANAGED_INTERFACE:
                    if (isMetaDataMode())
                        parseManagedInterface(meta, (ManagedInterface) anno);
                    break;
                case ACCESS:
                    if (isMetaDataMode())
                        parseAccess(meta, (Access)anno);
                    break;
                case CACHEABLE:
                    if (isMetaDataMode()) {
                        parseCache(meta, (Cacheable) anno);
                    }
                    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 (_cls.getSuperclass() != null &&
                !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;
    }