package io.ebeaninternal.server.deploy.parse; import io.ebean.annotation.Aggregation; import io.ebean.annotation.Avg; import io.ebean.annotation.DbMigration; import io.ebean.annotation.Index; import io.ebean.annotation.Indices; import io.ebean.annotation.Max; import io.ebean.annotation.Min; import io.ebean.annotation.Platform; import io.ebean.annotation.Sum; import io.ebean.config.NamingConvention; import io.ebean.config.dbplatform.DatabasePlatform; import io.ebean.util.AnnotationUtil; import io.ebeaninternal.server.deploy.meta.DeployBeanProperty; import javax.persistence.AttributeOverride; import javax.persistence.JoinColumn; import javax.persistence.JoinColumns; import javax.persistence.NamedQueries; import javax.persistence.NamedQuery; import java.lang.annotation.Annotation; import java.lang.reflect.Field; import java.util.Collections; import java.util.Set; /** * Provides some base methods for processing deployment annotations. All findAnnotation* methods * are capable to search for meta-annotations (annotation that has an other annotation) *

*

search algorithm for ONE annotation:

* * DFS (Depth-First-Search) is used. The algorithm is the same as it is used in Spring-Framework, * as the code is taken from there. *

*

search algoritm for a Set<Annotation> works a litte bit different, as it does not stop * on the first match, but continues searching down to the last corner to find all annotations.

*

*

To prevent endless recursion, the search algoritm tracks all visited annotations

*

*

Supports also "java 1.6 repeatable containers" like{@link JoinColumn} / {@link JoinColumns}.

*

*

This means, searching for JoinColumn will find them also if they are inside a * JoinColumns annotation

*/ abstract class AnnotationBase { final DatabasePlatform databasePlatform; protected final Platform platform; final NamingConvention namingConvention; final DeployUtil util; AnnotationBase(DeployUtil util) { this.util = util; this.databasePlatform = util.getDbPlatform(); this.platform = databasePlatform.getPlatform(); this.namingConvention = util.getNamingConvention(); } /** * read the deployment annotations. */ public abstract void parse(); /** * Checks string is null or empty . */ boolean isEmpty(String s) { return s == null || s.trim().isEmpty(); } T get(DeployBeanProperty prop, Class annClass) { return AnnotationUtil.get(prop.getField(), annClass); } boolean has(DeployBeanProperty prop, Class annClass) { return AnnotationUtil.has(prop.getField(), annClass); } Set annotationJoinColumns(DeployBeanProperty prop) { return AnnotationFind.joinColumns(prop.getField()); } Set annotationAttributeOverrides(DeployBeanProperty prop) { return AnnotationFind.attributeOverrides(prop.getField()); } Set annotationIndexes(DeployBeanProperty prop) { return AnnotationFind.indexes(prop.getField()); } Set annotationDbMigrations(DeployBeanProperty prop) { return AnnotationFind.dbMigrations(prop.getField()); } Set annotationClassIndexes(Class cls) { Set result = AnnotationUtil.typeGetAll(cls, Index.class); for (Indices index : AnnotationUtil.typeGetAll(cls, Indices.class)) { Collections.addAll(result, index.value()); } return result; } Set annotationClassNamedQuery(Class cls) { Set result = AnnotationUtil.typeGetAll(cls, NamedQuery.class); for (NamedQueries queries : AnnotationUtil.typeGetAll(cls, NamedQueries.class)) { Collections.addAll(result, queries.value()); } return result; } }