generate typesafe references to named queries, fetch profiles, entity graphs, fetch profiles
add support for about @FilterDef
This commit is contained in:
parent
2fb7cdd08b
commit
727a9b2c03
|
@ -23,7 +23,7 @@ import javax.tools.Diagnostic;
|
|||
import javax.tools.FileObject;
|
||||
|
||||
import org.hibernate.jpamodelgen.model.MetaAttribute;
|
||||
import org.hibernate.jpamodelgen.model.MetaEntity;
|
||||
import org.hibernate.jpamodelgen.model.Metamodel;
|
||||
import org.hibernate.jpamodelgen.util.Constants;
|
||||
import org.hibernate.jpamodelgen.util.TypeUtils;
|
||||
|
||||
|
@ -49,7 +49,7 @@ public final class ClassWriter {
|
|||
private ClassWriter() {
|
||||
}
|
||||
|
||||
public static void writeFile(MetaEntity entity, Context context) {
|
||||
public static void writeFile(Metamodel entity, Context context) {
|
||||
try {
|
||||
String metaModelPackage = entity.getPackageName();
|
||||
// need to generate the body first, since this will also update the required imports which need to
|
||||
|
@ -58,7 +58,7 @@ public final class ClassWriter {
|
|||
|
||||
FileObject fo = context.getProcessingEnvironment().getFiler().createSourceFile(
|
||||
getFullyQualifiedClassName( entity, metaModelPackage ),
|
||||
entity.getTypeElement()
|
||||
entity.getElement()
|
||||
);
|
||||
OutputStream os = fo.openOutputStream();
|
||||
PrintWriter pw = new PrintWriter( os );
|
||||
|
@ -94,46 +94,43 @@ public final class ClassWriter {
|
|||
*
|
||||
* @return body content
|
||||
*/
|
||||
private static StringBuffer generateBody(MetaEntity entity, Context context) {
|
||||
private static StringBuffer generateBody(Metamodel entity, Context context) {
|
||||
StringWriter sw = new StringWriter();
|
||||
PrintWriter pw = null;
|
||||
try {
|
||||
pw = new PrintWriter( sw );
|
||||
try ( PrintWriter pw = new PrintWriter(sw) ) {
|
||||
|
||||
if ( context.addGeneratedAnnotation() ) {
|
||||
pw.println( writeGeneratedAnnotation( entity, context ) );
|
||||
if (context.addGeneratedAnnotation()) {
|
||||
pw.println(writeGeneratedAnnotation(entity, context));
|
||||
}
|
||||
if ( context.isAddSuppressWarningsAnnotation() ) {
|
||||
pw.println( writeSuppressWarnings() );
|
||||
if (context.isAddSuppressWarningsAnnotation()) {
|
||||
pw.println(writeSuppressWarnings());
|
||||
}
|
||||
|
||||
pw.println( writeStaticMetaModelAnnotation( entity ) );
|
||||
if ( entity.getElement() instanceof TypeElement ) {
|
||||
pw.println(writeStaticMetaModelAnnotation(entity));
|
||||
}
|
||||
|
||||
printClassDeclaration( entity, pw, context );
|
||||
printClassDeclaration(entity, pw, context);
|
||||
|
||||
pw.println();
|
||||
|
||||
List<MetaAttribute> members = entity.getMembers();
|
||||
for ( MetaAttribute metaMember : members ) {
|
||||
pw.println( " " + metaMember.getAttributeDeclarationString() );
|
||||
for (MetaAttribute metaMember : members) {
|
||||
if (metaMember.hasTypedAttribute()) {
|
||||
pw.println(" " + metaMember.getAttributeDeclarationString());
|
||||
}
|
||||
}
|
||||
pw.println();
|
||||
for ( MetaAttribute metaMember : members ) {
|
||||
pw.println( " " + metaMember.getAttributeNameDeclarationString() );
|
||||
for (MetaAttribute metaMember : members) {
|
||||
pw.println(" " + metaMember.getAttributeNameDeclarationString());
|
||||
}
|
||||
|
||||
pw.println();
|
||||
pw.println( "}" );
|
||||
pw.println("}");
|
||||
return sw.getBuffer();
|
||||
}
|
||||
finally {
|
||||
if ( pw != null ) {
|
||||
pw.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void printClassDeclaration(MetaEntity entity, PrintWriter pw, Context context) {
|
||||
private static void printClassDeclaration(Metamodel entity, PrintWriter pw, Context context) {
|
||||
pw.print( "public abstract class " + entity.getSimpleName() + META_MODEL_CLASS_NAME_SUFFIX );
|
||||
|
||||
String superClassName = findMappedSuperClass( entity, context );
|
||||
|
@ -144,17 +141,20 @@ public final class ClassWriter {
|
|||
pw.println( " {" );
|
||||
}
|
||||
|
||||
private static @Nullable String findMappedSuperClass(MetaEntity entity, Context context) {
|
||||
TypeMirror superClass = entity.getTypeElement().getSuperclass();
|
||||
//superclass of Object is of NoType which returns some other kind
|
||||
while ( superClass.getKind() == TypeKind.DECLARED ) {
|
||||
//F..king Ch...t Have those people used their horrible APIs even once?
|
||||
final Element superClassElement = ( (DeclaredType) superClass ).asElement();
|
||||
String superClassName = ( (TypeElement) superClassElement ).getQualifiedName().toString();
|
||||
if ( extendsSuperMetaModel( superClassElement, entity.isMetaComplete(), context ) ) {
|
||||
return superClassName;
|
||||
private static @Nullable String findMappedSuperClass(Metamodel entity, Context context) {
|
||||
Element element = entity.getElement();
|
||||
if ( element instanceof TypeElement ) {
|
||||
TypeMirror superClass = ((TypeElement) element).getSuperclass();
|
||||
//superclass of Object is of NoType which returns some other kind
|
||||
while ( superClass.getKind() == TypeKind.DECLARED ) {
|
||||
//F..king Ch...t Have those people used their horrible APIs even once?
|
||||
final Element superClassElement = ( (DeclaredType) superClass ).asElement();
|
||||
String superClassName = ( (TypeElement) superClassElement ).getQualifiedName().toString();
|
||||
if ( extendsSuperMetaModel( superClassElement, entity.isMetaComplete(), context ) ) {
|
||||
return superClassName;
|
||||
}
|
||||
superClass = ( (TypeElement) superClassElement ).getSuperclass();
|
||||
}
|
||||
superClass = ( (TypeElement) superClassElement ).getSuperclass();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
@ -191,7 +191,7 @@ public final class ClassWriter {
|
|||
return false;
|
||||
}
|
||||
|
||||
private static String getFullyQualifiedClassName(MetaEntity entity, String metaModelPackage) {
|
||||
private static String getFullyQualifiedClassName(Metamodel entity, String metaModelPackage) {
|
||||
String fullyQualifiedClassName = "";
|
||||
if ( !metaModelPackage.isEmpty() ) {
|
||||
fullyQualifiedClassName = fullyQualifiedClassName + metaModelPackage + ".";
|
||||
|
@ -200,7 +200,7 @@ public final class ClassWriter {
|
|||
return fullyQualifiedClassName;
|
||||
}
|
||||
|
||||
private static String writeGeneratedAnnotation(MetaEntity entity, Context context) {
|
||||
private static String writeGeneratedAnnotation(Metamodel entity, Context context) {
|
||||
StringBuilder generatedAnnotation = new StringBuilder();
|
||||
generatedAnnotation.append( "@" )
|
||||
.append( entity.importType( "jakarta.annotation.Generated" ) )
|
||||
|
@ -221,7 +221,7 @@ public final class ClassWriter {
|
|||
return "@SuppressWarnings({ \"deprecation\", \"rawtypes\" })";
|
||||
}
|
||||
|
||||
private static String writeStaticMetaModelAnnotation(MetaEntity entity) {
|
||||
private static String writeStaticMetaModelAnnotation(Metamodel entity) {
|
||||
return "@" + entity.importType( "jakarta.persistence.metamodel.StaticMetamodel" ) + "(" + entity.getSimpleName() + ".class)";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ import javax.lang.model.util.Elements;
|
|||
import javax.lang.model.util.Types;
|
||||
import javax.tools.Diagnostic;
|
||||
|
||||
import org.hibernate.jpamodelgen.model.MetaEntity;
|
||||
import org.hibernate.jpamodelgen.model.Metamodel;
|
||||
import org.hibernate.jpamodelgen.util.AccessType;
|
||||
import org.hibernate.jpamodelgen.util.AccessTypeInformation;
|
||||
import org.hibernate.jpamodelgen.util.Constants;
|
||||
|
@ -37,15 +37,17 @@ public final class Context {
|
|||
/**
|
||||
* Used for keeping track of parsed entities and mapped super classes (xml + annotations).
|
||||
*/
|
||||
private final Map<String, MetaEntity> metaEntities = new HashMap<String, MetaEntity>();
|
||||
private final Map<String, Metamodel> metaEntities = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Used for keeping track of parsed embeddable entities. These entities have to be kept separate since
|
||||
* they are lazily initialized.
|
||||
*/
|
||||
private final Map<String, MetaEntity> metaEmbeddables = new HashMap<String, MetaEntity>();
|
||||
private final Map<String, Metamodel> metaEmbeddables = new HashMap<>();
|
||||
|
||||
private final Map<String, AccessTypeInformation> accessTypeInformation = new HashMap<String, AccessTypeInformation>();
|
||||
private final Map<String, Metamodel> metaAuxiliaries = new HashMap<>();
|
||||
|
||||
private final Map<String, AccessTypeInformation> accessTypeInformation = new HashMap<>();
|
||||
|
||||
private final ProcessingEnvironment pe;
|
||||
private final boolean logDebug;
|
||||
|
@ -146,15 +148,15 @@ public final class Context {
|
|||
return metaEntities.containsKey( fqcn );
|
||||
}
|
||||
|
||||
public @Nullable MetaEntity getMetaEntity(String fqcn) {
|
||||
public @Nullable Metamodel getMetaEntity(String fqcn) {
|
||||
return metaEntities.get( fqcn );
|
||||
}
|
||||
|
||||
public Collection<MetaEntity> getMetaEntities() {
|
||||
public Collection<Metamodel> getMetaEntities() {
|
||||
return metaEntities.values();
|
||||
}
|
||||
|
||||
public void addMetaEntity(String fqcn, MetaEntity metaEntity) {
|
||||
public void addMetaEntity(String fqcn, Metamodel metaEntity) {
|
||||
metaEntities.put( fqcn, metaEntity );
|
||||
}
|
||||
|
||||
|
@ -162,18 +164,30 @@ public final class Context {
|
|||
return metaEmbeddables.containsKey( fqcn );
|
||||
}
|
||||
|
||||
public @Nullable MetaEntity getMetaEmbeddable(String fqcn) {
|
||||
public @Nullable Metamodel getMetaEmbeddable(String fqcn) {
|
||||
return metaEmbeddables.get( fqcn );
|
||||
}
|
||||
|
||||
public void addMetaEmbeddable(String fqcn, MetaEntity metaEntity) {
|
||||
public void addMetaEmbeddable(String fqcn, Metamodel metaEntity) {
|
||||
metaEmbeddables.put( fqcn, metaEntity );
|
||||
}
|
||||
|
||||
public Collection<MetaEntity> getMetaEmbeddables() {
|
||||
public Collection<Metamodel> getMetaEmbeddables() {
|
||||
return metaEmbeddables.values();
|
||||
}
|
||||
|
||||
public @Nullable Metamodel getMetaAuxiliary(String fqcn) {
|
||||
return metaAuxiliaries.get( fqcn );
|
||||
}
|
||||
|
||||
public Collection<Metamodel> getMetaAuxiliaries() {
|
||||
return metaAuxiliaries.values();
|
||||
}
|
||||
|
||||
public void addMetaAuxiliary(String fqcn, Metamodel metamodel) {
|
||||
metaAuxiliaries.put( fqcn, metamodel);
|
||||
}
|
||||
|
||||
public void addAccessTypeInformation(String fqcn, AccessTypeInformation info) {
|
||||
accessTypeInformation.put( fqcn, info );
|
||||
}
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
*/
|
||||
package org.hibernate.jpamodelgen;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
@ -20,6 +19,7 @@ import javax.lang.model.SourceVersion;
|
|||
import javax.lang.model.element.AnnotationMirror;
|
||||
import javax.lang.model.element.Element;
|
||||
import javax.lang.model.element.ElementKind;
|
||||
import javax.lang.model.element.PackageElement;
|
||||
import javax.lang.model.element.TypeElement;
|
||||
import javax.lang.model.type.DeclaredType;
|
||||
import javax.lang.model.type.ExecutableType;
|
||||
|
@ -30,7 +30,8 @@ import javax.lang.model.util.SimpleTypeVisitor6;
|
|||
import javax.tools.Diagnostic;
|
||||
|
||||
import org.hibernate.jpamodelgen.annotation.AnnotationMetaEntity;
|
||||
import org.hibernate.jpamodelgen.model.MetaEntity;
|
||||
import org.hibernate.jpamodelgen.annotation.AnnotationMetaPackage;
|
||||
import org.hibernate.jpamodelgen.model.Metamodel;
|
||||
import org.hibernate.jpamodelgen.util.Constants;
|
||||
import org.hibernate.jpamodelgen.util.StringUtil;
|
||||
import org.hibernate.jpamodelgen.util.TypeUtils;
|
||||
|
@ -132,6 +133,10 @@ public class JPAMetaModelEntityProcessor extends AbstractProcessor {
|
|||
context.logMessage( Diagnostic.Kind.OTHER, "Processing annotated class " + element.toString() );
|
||||
handleRootElementAnnotationMirrors( element );
|
||||
}
|
||||
else if ( hasAuxiliaryAnnotations( element ) ) {
|
||||
context.logMessage( Diagnostic.Kind.OTHER, "Processing annotated class " + element.toString() );
|
||||
handleRootElementAuxiliaryAnnotationMirrors( element );
|
||||
}
|
||||
}
|
||||
|
||||
createMetaModelClasses();
|
||||
|
@ -139,7 +144,17 @@ public class JPAMetaModelEntityProcessor extends AbstractProcessor {
|
|||
}
|
||||
|
||||
private void createMetaModelClasses() {
|
||||
for ( MetaEntity entity : context.getMetaEntities() ) {
|
||||
|
||||
for ( Metamodel aux : context.getMetaAuxiliaries() ) {
|
||||
if ( context.isAlreadyGenerated( aux.getQualifiedName() ) ) {
|
||||
continue;
|
||||
}
|
||||
context.logMessage( Diagnostic.Kind.OTHER, "Writing meta model for auxiliary " + aux );
|
||||
ClassWriter.writeFile( aux, context );
|
||||
context.markGenerated( aux.getQualifiedName() );
|
||||
}
|
||||
|
||||
for ( Metamodel entity : context.getMetaEntities() ) {
|
||||
if ( context.isAlreadyGenerated( entity.getQualifiedName() ) ) {
|
||||
continue;
|
||||
}
|
||||
|
@ -150,11 +165,11 @@ public class JPAMetaModelEntityProcessor extends AbstractProcessor {
|
|||
|
||||
// we cannot process the delayed entities in any order. There might be dependencies between them.
|
||||
// we need to process the top level entities first
|
||||
Collection<MetaEntity> toProcessEntities = context.getMetaEmbeddables();
|
||||
Collection<Metamodel> toProcessEntities = context.getMetaEmbeddables();
|
||||
while ( !toProcessEntities.isEmpty() ) {
|
||||
Set<MetaEntity> processedEntities = new HashSet<MetaEntity>();
|
||||
Set<Metamodel> processedEntities = new HashSet<Metamodel>();
|
||||
int toProcessCountBeforeLoop = toProcessEntities.size();
|
||||
for ( MetaEntity entity : toProcessEntities ) {
|
||||
for ( Metamodel entity : toProcessEntities ) {
|
||||
// see METAGEN-36
|
||||
if ( context.isAlreadyGenerated( entity.getQualifiedName() ) ) {
|
||||
processedEntities.add( entity );
|
||||
|
@ -179,32 +194,33 @@ public class JPAMetaModelEntityProcessor extends AbstractProcessor {
|
|||
}
|
||||
}
|
||||
|
||||
private boolean modelGenerationNeedsToBeDeferred(Collection<MetaEntity> entities, MetaEntity containedEntity) {
|
||||
ContainsAttributeTypeVisitor visitor = new ContainsAttributeTypeVisitor(
|
||||
containedEntity.getTypeElement(), context
|
||||
);
|
||||
for ( MetaEntity entity : entities ) {
|
||||
if ( entity.equals( containedEntity ) ) {
|
||||
continue;
|
||||
}
|
||||
for ( Element subElement : ElementFilter.fieldsIn( entity.getTypeElement().getEnclosedElements() ) ) {
|
||||
TypeMirror mirror = subElement.asType();
|
||||
if ( !TypeKind.DECLARED.equals( mirror.getKind() ) ) {
|
||||
private boolean modelGenerationNeedsToBeDeferred(Collection<Metamodel> entities, Metamodel containedEntity) {
|
||||
Element element = containedEntity.getElement();
|
||||
if ( element instanceof TypeElement ) {
|
||||
ContainsAttributeTypeVisitor visitor = new ContainsAttributeTypeVisitor( (TypeElement) element, context );
|
||||
for ( Metamodel entity : entities ) {
|
||||
if ( entity.equals( containedEntity ) ) {
|
||||
continue;
|
||||
}
|
||||
boolean contains = mirror.accept( visitor, subElement );
|
||||
if ( contains ) {
|
||||
return true;
|
||||
for ( Element subElement : ElementFilter.fieldsIn( entity.getElement().getEnclosedElements() ) ) {
|
||||
TypeMirror mirror = subElement.asType();
|
||||
if ( !TypeKind.DECLARED.equals( mirror.getKind() ) ) {
|
||||
continue;
|
||||
}
|
||||
boolean contains = mirror.accept( visitor, subElement );
|
||||
if ( contains ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
for ( Element subElement : ElementFilter.methodsIn( entity.getTypeElement().getEnclosedElements() ) ) {
|
||||
TypeMirror mirror = subElement.asType();
|
||||
if ( !TypeKind.DECLARED.equals( mirror.getKind() ) ) {
|
||||
continue;
|
||||
}
|
||||
boolean contains = mirror.accept( visitor, subElement );
|
||||
if ( contains ) {
|
||||
return true;
|
||||
for ( Element subElement : ElementFilter.methodsIn( entity.getElement().getEnclosedElements() ) ) {
|
||||
TypeMirror mirror = subElement.asType();
|
||||
if ( !TypeKind.DECLARED.equals( mirror.getKind() ) ) {
|
||||
continue;
|
||||
}
|
||||
boolean contains = mirror.accept( visitor, subElement );
|
||||
if ( contains ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -220,6 +236,28 @@ public class JPAMetaModelEntityProcessor extends AbstractProcessor {
|
|||
);
|
||||
}
|
||||
|
||||
private boolean hasAuxiliaryAnnotations(Element element) {
|
||||
return TypeUtils.containsAnnotation(
|
||||
element,
|
||||
Constants.NAMED_QUERY,
|
||||
Constants.NAMED_QUERIES,
|
||||
Constants.NAMED_NATIVE_QUERY,
|
||||
Constants.NAMED_NATIVE_QUERIES,
|
||||
Constants.SQL_RESULT_SET_MAPPING,
|
||||
Constants.SQL_RESULT_SET_MAPPINGS,
|
||||
Constants.NAMED_ENTITY_GRAPH,
|
||||
Constants.NAMED_ENTITY_GRAPHS,
|
||||
Constants.HIB_NAMED_QUERY,
|
||||
Constants.HIB_NAMED_QUERIES,
|
||||
Constants.HIB_NAMED_NATIVE_QUERY,
|
||||
Constants.HIB_NAMED_NATIVE_QUERIES,
|
||||
Constants.HIB_FETCH_PROFILE,
|
||||
Constants.HIB_FETCH_PROFILES,
|
||||
Constants.HIB_FILTER_DEF,
|
||||
Constants.HIB_FILTER_DEFS
|
||||
);
|
||||
}
|
||||
|
||||
private void handleRootElementAnnotationMirrors(final Element element) {
|
||||
List<? extends AnnotationMirror> annotationMirrors = element.getAnnotationMirrors();
|
||||
for ( AnnotationMirror mirror : annotationMirrors ) {
|
||||
|
@ -228,7 +266,7 @@ public class JPAMetaModelEntityProcessor extends AbstractProcessor {
|
|||
}
|
||||
|
||||
String fqn = ( (TypeElement) element ).getQualifiedName().toString();
|
||||
MetaEntity alreadyExistingMetaEntity = tryGettingExistingEntityFromContext( mirror, fqn );
|
||||
Metamodel alreadyExistingMetaEntity = tryGettingExistingEntityFromContext( mirror, fqn );
|
||||
if ( alreadyExistingMetaEntity != null && alreadyExistingMetaEntity.isMetaComplete() ) {
|
||||
String msg = "Skipping processing of annotations for " + fqn + " since xml configuration is metadata complete.";
|
||||
context.logMessage( Diagnostic.Kind.OTHER, msg );
|
||||
|
@ -251,8 +289,22 @@ public class JPAMetaModelEntityProcessor extends AbstractProcessor {
|
|||
}
|
||||
}
|
||||
|
||||
private @Nullable MetaEntity tryGettingExistingEntityFromContext(AnnotationMirror mirror, String fqn) {
|
||||
MetaEntity alreadyExistingMetaEntity = null;
|
||||
private void handleRootElementAuxiliaryAnnotationMirrors(final Element element) {
|
||||
if ( element instanceof TypeElement ) {
|
||||
AnnotationMetaEntity metaEntity =
|
||||
AnnotationMetaEntity.create( (TypeElement) element, context, false );
|
||||
context.addMetaAuxiliary( metaEntity.getQualifiedName(), metaEntity );
|
||||
}
|
||||
else if ( element instanceof PackageElement ) {
|
||||
AnnotationMetaPackage metaEntity =
|
||||
AnnotationMetaPackage.create( (PackageElement) element, context );
|
||||
context.addMetaAuxiliary( metaEntity.getQualifiedName(), metaEntity );
|
||||
}
|
||||
//TODO: handle PackageElement
|
||||
}
|
||||
|
||||
private @Nullable Metamodel tryGettingExistingEntityFromContext(AnnotationMirror mirror, String fqn) {
|
||||
Metamodel alreadyExistingMetaEntity = null;
|
||||
if ( TypeUtils.isAnnotationMirrorOfType( mirror, Constants.ENTITY )
|
||||
|| TypeUtils.isAnnotationMirrorOfType( mirror, Constants.MAPPED_SUPERCLASS ) ) {
|
||||
alreadyExistingMetaEntity = context.getMetaEntity( fqn );
|
||||
|
@ -305,27 +357,21 @@ public class JPAMetaModelEntityProcessor extends AbstractProcessor {
|
|||
returnedElement = (TypeElement) collectionElement;
|
||||
}
|
||||
|
||||
if ( type.getQualifiedName().toString().equals( returnedElement.getQualifiedName().toString() ) ) {
|
||||
return Boolean.TRUE;
|
||||
}
|
||||
else {
|
||||
return Boolean.FALSE;
|
||||
}
|
||||
return type.getQualifiedName().toString().equals( returnedElement.getQualifiedName().toString() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean visitExecutable(ExecutableType t, Element element) {
|
||||
if ( !element.getKind().equals( ElementKind.METHOD ) ) {
|
||||
return Boolean.FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
String string = element.getSimpleName().toString();
|
||||
if ( !StringUtil.isProperty( string, TypeUtils.toTypeString( t.getReturnType() ) ) ) {
|
||||
return Boolean.FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
TypeMirror returnType = t.getReturnType();
|
||||
return returnType.accept( this, element );
|
||||
return t.getReturnType().accept( this, element );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.jpamodelgen.annotation;
|
||||
|
||||
import org.hibernate.jpamodelgen.model.Metamodel;
|
||||
import org.hibernate.jpamodelgen.util.Constants;
|
||||
import org.hibernate.jpamodelgen.util.TypeUtils;
|
||||
|
||||
import javax.lang.model.element.AnnotationMirror;
|
||||
import java.util.List;
|
||||
|
||||
public abstract class AnnotationMeta implements Metamodel {
|
||||
|
||||
void addAuxiliaryMembers() {
|
||||
addAuxiliaryMembersForAnnotation( Constants.NAMED_QUERY, "QUERY_" );
|
||||
addAuxiliaryMembersForRepeatableAnnotation( Constants.NAMED_QUERIES, "QUERY_" );
|
||||
addAuxiliaryMembersForAnnotation( Constants.NAMED_NATIVE_QUERY, "QUERY_" );
|
||||
addAuxiliaryMembersForRepeatableAnnotation( Constants.NAMED_NATIVE_QUERIES, "QUERY_" );
|
||||
addAuxiliaryMembersForAnnotation( Constants.SQL_RESULT_SET_MAPPING, "MAPPING_" );
|
||||
addAuxiliaryMembersForRepeatableAnnotation( Constants.SQL_RESULT_SET_MAPPINGS, "MAPPING_" );
|
||||
addAuxiliaryMembersForAnnotation( Constants.NAMED_ENTITY_GRAPH, "GRAPH_" );
|
||||
addAuxiliaryMembersForRepeatableAnnotation( Constants.NAMED_ENTITY_GRAPHS, "GRAPH_" );
|
||||
|
||||
addAuxiliaryMembersForAnnotation( Constants.HIB_NAMED_QUERY, "QUERY_" );
|
||||
addAuxiliaryMembersForRepeatableAnnotation( Constants.HIB_NAMED_QUERIES, "QUERY_" );
|
||||
addAuxiliaryMembersForAnnotation( Constants.HIB_NAMED_NATIVE_QUERY, "QUERY_" );
|
||||
addAuxiliaryMembersForRepeatableAnnotation( Constants.HIB_NAMED_NATIVE_QUERIES, "QUERY_" );
|
||||
addAuxiliaryMembersForAnnotation( Constants.HIB_FETCH_PROFILE, "PROFILE_" );
|
||||
addAuxiliaryMembersForRepeatableAnnotation( Constants.HIB_FETCH_PROFILES, "PROFILE_" );
|
||||
addAuxiliaryMembersForAnnotation( Constants.HIB_FILTER_DEF, "FILTER_" );
|
||||
addAuxiliaryMembersForRepeatableAnnotation( Constants.HIB_FILTER_DEFS, "FILTER_" );
|
||||
}
|
||||
|
||||
private void addAuxiliaryMembersForRepeatableAnnotation(String annotationName, String prefix) {
|
||||
AnnotationMirror mirror = TypeUtils.getAnnotationMirror( getElement(), annotationName );
|
||||
if ( mirror != null ) {
|
||||
mirror.getElementValues().forEach((key, value) -> {
|
||||
if ( key.getSimpleName().contentEquals("value") ) {
|
||||
List<? extends AnnotationMirror> values =
|
||||
(List<? extends AnnotationMirror>) value.getValue();
|
||||
for ( AnnotationMirror annotationMirror : values ) {
|
||||
addAuxiliaryMembersForMirror( annotationMirror, prefix );
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void addAuxiliaryMembersForAnnotation(String annotationName, String prefix) {
|
||||
AnnotationMirror mirror = TypeUtils.getAnnotationMirror( getElement(), annotationName);
|
||||
if ( mirror != null ) {
|
||||
addAuxiliaryMembersForMirror( mirror, prefix );
|
||||
}
|
||||
}
|
||||
|
||||
private void addAuxiliaryMembersForMirror(AnnotationMirror mirror, String prefix) {
|
||||
mirror.getElementValues().forEach((key, value) -> {
|
||||
if ( key.getSimpleName().contentEquals("name") ) {
|
||||
String name = value.getValue().toString();
|
||||
putMember( prefix + name, new NameMetaAttribute( this, name, prefix ) );
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
abstract void putMember(String name, NameMetaAttribute nameMetaAttribute);
|
||||
}
|
|
@ -7,14 +7,12 @@
|
|||
package org.hibernate.jpamodelgen.annotation;
|
||||
|
||||
import java.beans.Introspector;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javax.lang.model.element.Element;
|
||||
import javax.lang.model.element.ElementKind;
|
||||
import javax.lang.model.util.Elements;
|
||||
|
||||
import org.hibernate.jpamodelgen.model.MetaAttribute;
|
||||
import org.hibernate.jpamodelgen.model.MetaEntity;
|
||||
import org.hibernate.jpamodelgen.model.Metamodel;
|
||||
import org.hibernate.jpamodelgen.util.StringUtil;
|
||||
|
||||
/**
|
||||
|
@ -36,6 +34,11 @@ public abstract class AnnotationMetaAttribute implements MetaAttribute {
|
|||
this.type = type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasTypedAttribute() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAttributeDeclarationString() {
|
||||
return new StringBuilder().append( "public static volatile " )
|
||||
|
@ -64,6 +67,7 @@ public abstract class AnnotationMetaAttribute implements MetaAttribute {
|
|||
.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPropertyName() {
|
||||
Elements elementsUtil = parent.getContext().getElementUtils();
|
||||
if ( element.getKind() == ElementKind.FIELD ) {
|
||||
|
@ -84,12 +88,15 @@ public abstract class AnnotationMetaAttribute implements MetaAttribute {
|
|||
}
|
||||
}
|
||||
|
||||
public MetaEntity getHostingEntity() {
|
||||
@Override
|
||||
public Metamodel getHostingEntity() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public abstract String getMetaType();
|
||||
|
||||
@Override
|
||||
public String getTypeDeclaration() {
|
||||
return type;
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@ import org.hibernate.jpamodelgen.Context;
|
|||
import org.hibernate.jpamodelgen.ImportContextImpl;
|
||||
import org.hibernate.jpamodelgen.model.ImportContext;
|
||||
import org.hibernate.jpamodelgen.model.MetaAttribute;
|
||||
import org.hibernate.jpamodelgen.model.MetaEntity;
|
||||
import org.hibernate.jpamodelgen.model.Metamodel;
|
||||
import org.hibernate.jpamodelgen.util.AccessType;
|
||||
import org.hibernate.jpamodelgen.util.AccessTypeInformation;
|
||||
import org.hibernate.jpamodelgen.util.Constants;
|
||||
|
@ -38,7 +38,7 @@ import org.hibernate.jpamodelgen.util.TypeUtils;
|
|||
* @author Hardy Ferentschik
|
||||
* @author Emmanuel Bernard
|
||||
*/
|
||||
public class AnnotationMetaEntity implements MetaEntity {
|
||||
public class AnnotationMetaEntity extends AnnotationMeta {
|
||||
|
||||
private final ImportContext importContext;
|
||||
private final TypeElement element;
|
||||
|
@ -50,12 +50,12 @@ public class AnnotationMetaEntity implements MetaEntity {
|
|||
/**
|
||||
* Whether the members of this type have already been initialized or not.
|
||||
* <p>
|
||||
* Embeddables and mapped super-classes need to be lazily initialized since the access type may be determined by
|
||||
* the class which is embedding or sub-classing the entity or super-class. This might not be known until
|
||||
* Embeddables and mapped superclasses need to be lazily initialized since the access type may be determined by
|
||||
* the class which is embedding or subclassing the entity or superclass. This might not be known until
|
||||
* annotations are processed.
|
||||
* <p>
|
||||
* Also note, that if two different classes with different access types embed this entity or extend this mapped
|
||||
* super-class, the access type of the embeddable/super-class will be the one of the last embedding/sub-classing
|
||||
* super-class, the access type of the embeddable/superclass will be the one of the last embedding/subclassing
|
||||
* entity processed. The result is not determined (that's ok according to the spec).
|
||||
*/
|
||||
private boolean initialized;
|
||||
|
@ -65,7 +65,7 @@ public class AnnotationMetaEntity implements MetaEntity {
|
|||
* lazily is required for embeddedables and mapped supertypes to only pull in those members matching the access
|
||||
* type as configured via the embedding entity or subclass (also see METAGEN-85).
|
||||
*/
|
||||
private MetaEntity entityToMerge;
|
||||
private Metamodel entityToMerge;
|
||||
|
||||
public AnnotationMetaEntity(TypeElement element, Context context) {
|
||||
this.element = element;
|
||||
|
@ -90,14 +90,17 @@ public class AnnotationMetaEntity implements MetaEntity {
|
|||
return context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String getSimpleName() {
|
||||
return element.getSimpleName().toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String getQualifiedName() {
|
||||
return element.getQualifiedName().toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String getPackageName() {
|
||||
return getPackageName( context, element );
|
||||
}
|
||||
|
@ -107,6 +110,7 @@ public class AnnotationMetaEntity implements MetaEntity {
|
|||
return context.getElementUtils().getName( packageOf.getQualifiedName() ).toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<MetaAttribute> getMembers() {
|
||||
if ( !initialized ) {
|
||||
init();
|
||||
|
@ -115,7 +119,7 @@ public class AnnotationMetaEntity implements MetaEntity {
|
|||
}
|
||||
}
|
||||
|
||||
return new ArrayList<MetaAttribute>( members.values() );
|
||||
return new ArrayList<>( members.values() );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -133,7 +137,7 @@ public class AnnotationMetaEntity implements MetaEntity {
|
|||
}
|
||||
}
|
||||
|
||||
public void mergeInMembers(MetaEntity other) {
|
||||
public void mergeInMembers(Metamodel other) {
|
||||
// store the entity in order do the merge lazily in case of a non-initialized embeddedable or mapped superclass
|
||||
if ( !initialized ) {
|
||||
this.entityToMerge = other;
|
||||
|
@ -143,22 +147,31 @@ public class AnnotationMetaEntity implements MetaEntity {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String generateImports() {
|
||||
return importContext.generateImports();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String importType(String fqcn) {
|
||||
return importContext.importType( fqcn );
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String staticImport(String fqcn, String member) {
|
||||
return importContext.staticImport( fqcn, member );
|
||||
}
|
||||
|
||||
public final TypeElement getTypeElement() {
|
||||
@Override
|
||||
public final TypeElement getElement() {
|
||||
return element;
|
||||
}
|
||||
|
||||
@Override
|
||||
void putMember(String name, NameMetaAttribute nameMetaAttribute) {
|
||||
members.put( name, nameMetaAttribute );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
|
@ -169,16 +182,12 @@ public class AnnotationMetaEntity implements MetaEntity {
|
|||
return sb.toString();
|
||||
}
|
||||
|
||||
protected TypeElement getElement() {
|
||||
return element;
|
||||
}
|
||||
|
||||
protected final void init() {
|
||||
getContext().logMessage( Diagnostic.Kind.OTHER, "Initializing type " + getQualifiedName() + "." );
|
||||
|
||||
TypeUtils.determineAccessTypeForHierarchy( element, context );
|
||||
AccessTypeInformation accessTypeInfo = context.getAccessTypeInfo( getQualifiedName() );
|
||||
entityAccessTypeInfo = NullnessUtil.castNonNull(accessTypeInfo);
|
||||
entityAccessTypeInfo = NullnessUtil.castNonNull( accessTypeInfo );
|
||||
|
||||
List<? extends Element> fieldsOfClass = ElementFilter.fieldsIn( element.getEnclosedElements() );
|
||||
addPersistentMembers( fieldsOfClass, AccessType.FIELD );
|
||||
|
@ -186,16 +195,19 @@ public class AnnotationMetaEntity implements MetaEntity {
|
|||
List<? extends Element> methodsOfClass = ElementFilter.methodsIn( element.getEnclosedElements() );
|
||||
List<Element> gettersAndSettersOfClass = new ArrayList<>();
|
||||
|
||||
for (Element rawMethodOfClass: methodsOfClass) {
|
||||
if ( isGetterOrSetter( rawMethodOfClass)) {
|
||||
gettersAndSettersOfClass.add(rawMethodOfClass);
|
||||
for ( Element rawMethodOfClass: methodsOfClass ) {
|
||||
if ( isGetterOrSetter( rawMethodOfClass ) ) {
|
||||
gettersAndSettersOfClass.add( rawMethodOfClass );
|
||||
}
|
||||
}
|
||||
addPersistentMembers( gettersAndSettersOfClass, AccessType.PROPERTY );
|
||||
|
||||
addAuxiliaryMembers();
|
||||
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check if method respects Java Bean conventions for getter and setters.
|
||||
*
|
||||
|
@ -246,4 +258,5 @@ public class AnnotationMetaEntity implements MetaEntity {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,127 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.jpamodelgen.annotation;
|
||||
|
||||
import org.hibernate.jpamodelgen.Context;
|
||||
import org.hibernate.jpamodelgen.ImportContextImpl;
|
||||
import org.hibernate.jpamodelgen.model.ImportContext;
|
||||
import org.hibernate.jpamodelgen.model.MetaAttribute;
|
||||
|
||||
import javax.lang.model.element.PackageElement;
|
||||
import javax.tools.Diagnostic;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Class used to collect meta information about an annotated package.
|
||||
*
|
||||
* @author Gavin King
|
||||
*/
|
||||
public class AnnotationMetaPackage extends AnnotationMeta {
|
||||
|
||||
private final ImportContext importContext;
|
||||
private final PackageElement element;
|
||||
private final Map<String, MetaAttribute> members;
|
||||
private final Context context;
|
||||
|
||||
/**
|
||||
* Whether the members of this type have already been initialized or not.
|
||||
*/
|
||||
private boolean initialized;
|
||||
|
||||
public AnnotationMetaPackage(PackageElement element, Context context) {
|
||||
this.element = element;
|
||||
this.context = context;
|
||||
this.members = new HashMap<>();
|
||||
this.importContext = new ImportContextImpl( getPackageName( context, element ) );
|
||||
}
|
||||
|
||||
public static AnnotationMetaPackage create(PackageElement element, Context context) {
|
||||
return new AnnotationMetaPackage( element, context );
|
||||
}
|
||||
|
||||
public final Context getContext() {
|
||||
return context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String getSimpleName() {
|
||||
return element.getSimpleName().toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String getQualifiedName() {
|
||||
return element.getQualifiedName().toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String getPackageName() {
|
||||
return getPackageName( context, element );
|
||||
}
|
||||
|
||||
private static String getPackageName(Context context, PackageElement packageOf) {
|
||||
return context.getElementUtils().getName( packageOf.getQualifiedName() ).toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<MetaAttribute> getMembers() {
|
||||
if ( !initialized ) {
|
||||
init();
|
||||
}
|
||||
|
||||
return new ArrayList<>( members.values() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMetaComplete() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String generateImports() {
|
||||
return importContext.generateImports();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String importType(String fqcn) {
|
||||
return importContext.importType( fqcn );
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String staticImport(String fqcn, String member) {
|
||||
return importContext.staticImport( fqcn, member );
|
||||
}
|
||||
|
||||
@Override
|
||||
public final PackageElement getElement() {
|
||||
return element;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
sb.append( "AnnotationMetaPackage" );
|
||||
sb.append( "{element=" ).append( element );
|
||||
sb.append( '}' );
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
protected final void init() {
|
||||
getContext().logMessage( Diagnostic.Kind.OTHER, "Initializing type " + getQualifiedName() + "." );
|
||||
|
||||
addAuxiliaryMembers();
|
||||
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
void putMember(String name, NameMetaAttribute nameMetaAttribute) {
|
||||
members.put( name, nameMetaAttribute );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.jpamodelgen.annotation;
|
||||
|
||||
import org.hibernate.jpamodelgen.model.MetaAttribute;
|
||||
import org.hibernate.jpamodelgen.model.Metamodel;
|
||||
import org.hibernate.jpamodelgen.util.StringUtil;
|
||||
|
||||
/**
|
||||
* @author Gavin King
|
||||
*/
|
||||
class NameMetaAttribute implements MetaAttribute {
|
||||
private final Metamodel annotationMetaEntity;
|
||||
private final String name;
|
||||
private final String prefix;
|
||||
|
||||
public NameMetaAttribute(Metamodel annotationMetaEntity, String name, String prefix) {
|
||||
this.annotationMetaEntity = annotationMetaEntity;
|
||||
this.name = name;
|
||||
this.prefix = prefix;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasTypedAttribute() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAttributeDeclarationString() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAttributeNameDeclarationString() {
|
||||
return new StringBuilder()
|
||||
.append("public static final ")
|
||||
.append(annotationMetaEntity.importType(String.class.getName()))
|
||||
.append(" ")
|
||||
.append(prefix)
|
||||
.append(StringUtil.nameToFieldName(name))
|
||||
.append(" = ")
|
||||
.append("\"")
|
||||
.append(name)
|
||||
.append("\"")
|
||||
.append(";")
|
||||
.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMetaType() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPropertyName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTypeDeclaration() {
|
||||
return "java.lang.String";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Metamodel getHostingEntity() {
|
||||
return annotationMetaEntity;
|
||||
}
|
||||
}
|
|
@ -11,6 +11,8 @@ package org.hibernate.jpamodelgen.model;
|
|||
*/
|
||||
public interface MetaAttribute {
|
||||
|
||||
boolean hasTypedAttribute();
|
||||
|
||||
String getAttributeDeclarationString();
|
||||
|
||||
String getAttributeNameDeclarationString();
|
||||
|
@ -21,6 +23,6 @@ public interface MetaAttribute {
|
|||
|
||||
String getTypeDeclaration();
|
||||
|
||||
MetaEntity getHostingEntity();
|
||||
Metamodel getHostingEntity();
|
||||
|
||||
}
|
||||
|
|
|
@ -7,12 +7,12 @@
|
|||
package org.hibernate.jpamodelgen.model;
|
||||
|
||||
import java.util.List;
|
||||
import javax.lang.model.element.TypeElement;
|
||||
import javax.lang.model.element.Element;
|
||||
|
||||
/**
|
||||
* @author Hardy Ferentschik
|
||||
*/
|
||||
public interface MetaEntity extends ImportContext {
|
||||
public interface Metamodel extends ImportContext {
|
||||
String getSimpleName();
|
||||
|
||||
String getQualifiedName();
|
||||
|
@ -27,7 +27,7 @@ public interface MetaEntity extends ImportContext {
|
|||
|
||||
String staticImport(String fqcn, String member);
|
||||
|
||||
TypeElement getTypeElement();
|
||||
Element getElement();
|
||||
|
||||
boolean isMetaComplete();
|
||||
}
|
|
@ -13,7 +13,7 @@ import java.util.Map;
|
|||
* @author Hardy Ferentschik
|
||||
*/
|
||||
public final class Constants {
|
||||
// we are trying to to reference jpa annotations directly
|
||||
// we are trying to reference jpa annotations directly
|
||||
public static final String ENTITY = "jakarta.persistence.Entity";
|
||||
public static final String MAPPED_SUPERCLASS = "jakarta.persistence.MappedSuperclass";
|
||||
public static final String EMBEDDABLE = "jakarta.persistence.Embeddable";
|
||||
|
@ -32,6 +32,24 @@ public final class Constants {
|
|||
public static final String CONVERT = "jakarta.persistence.Convert";
|
||||
public static final String HIBERNATE_TYPE = "org.hibernate.annotations.Type";
|
||||
|
||||
public static final String NAMED_QUERY = "jakarta.persistence.NamedQuery";
|
||||
public static final String NAMED_QUERIES = "jakarta.persistence.NamedQueries";
|
||||
public static final String NAMED_NATIVE_QUERY = "jakarta.persistence.NamedNativeQuery";
|
||||
public static final String NAMED_NATIVE_QUERIES = "jakarta.persistence.NamedNativeQueries";
|
||||
public static final String SQL_RESULT_SET_MAPPING = "jakarta.persistence.SqlResultSetMapping";
|
||||
public static final String SQL_RESULT_SET_MAPPINGS = "jakarta.persistence.SqlResultSetMappings";
|
||||
public static final String NAMED_ENTITY_GRAPH = "jakarta.persistence.NamedEntityGraph";
|
||||
public static final String NAMED_ENTITY_GRAPHS = "jakarta.persistence.NamedEntityGraphs";
|
||||
|
||||
public static final String HIB_NAMED_QUERY = "org.hibernate.annotations.NamedQuery";
|
||||
public static final String HIB_NAMED_QUERIES = "org.hibernate.annotations.NamedQueries";
|
||||
public static final String HIB_NAMED_NATIVE_QUERY = "org.hibernate.annotations.NamedNativeQuery";
|
||||
public static final String HIB_NAMED_NATIVE_QUERIES = "org.hibernate.annotations.NamedNativeQueries";
|
||||
public static final String HIB_FETCH_PROFILE = "org.hibernate.annotations.FetchProfile";
|
||||
public static final String HIB_FETCH_PROFILES = "org.hibernate.annotations.FetchProfiles";
|
||||
public static final String HIB_FILTER_DEF = "org.hibernate.annotations.FilterDef";
|
||||
public static final String HIB_FILTER_DEFS = "org.hibernate.annotations.FilterDefs";
|
||||
|
||||
public static final Map<String, String> COLLECTIONS = allCollectionTypes();
|
||||
|
||||
private static Map<String, String> allCollectionTypes() {
|
||||
|
|
|
@ -93,6 +93,14 @@ public final class StringUtil {
|
|||
}
|
||||
}
|
||||
|
||||
public static String nameToFieldName(String name){
|
||||
return getUpperUnderscoreCaseFromLowerCamelCase(nameToMethodName(name));
|
||||
}
|
||||
|
||||
public static String nameToMethodName(String name) {
|
||||
return name.replaceAll("[\\s.\\-!@#%=+/*^&|(){}\\[\\]]", "_");
|
||||
}
|
||||
|
||||
public static String getUpperUnderscoreCaseFromLowerCamelCase(String lowerCamelCaseString){
|
||||
return lowerCamelCaseString.replaceAll("(.)(\\p{Upper})", "$1_$2").toUpperCase();
|
||||
}
|
||||
|
|
|
@ -6,11 +6,12 @@
|
|||
*/
|
||||
package org.hibernate.jpamodelgen.util;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import javax.lang.model.element.AnnotationMirror;
|
||||
import javax.lang.model.element.AnnotationValue;
|
||||
import javax.lang.model.element.Element;
|
||||
|
@ -138,7 +139,7 @@ public final class TypeUtils {
|
|||
assert element != null;
|
||||
assert annotations != null;
|
||||
|
||||
List<String> annotationClassNames = new ArrayList<String>();
|
||||
Set<String> annotationClassNames = new HashSet<>();
|
||||
Collections.addAll( annotationClassNames, annotations );
|
||||
|
||||
List<? extends AnnotationMirror> annotationMirrors = element.getAnnotationMirrors();
|
||||
|
|
|
@ -7,12 +7,9 @@
|
|||
package org.hibernate.jpamodelgen.xml;
|
||||
|
||||
import org.hibernate.jpamodelgen.model.MetaAttribute;
|
||||
import org.hibernate.jpamodelgen.model.MetaEntity;
|
||||
import org.hibernate.jpamodelgen.model.Metamodel;
|
||||
import org.hibernate.jpamodelgen.util.StringUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Hardy Ferentschik
|
||||
*/
|
||||
|
@ -28,6 +25,11 @@ public abstract class XmlMetaAttribute implements MetaAttribute {
|
|||
this.type = type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasTypedAttribute() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAttributeDeclarationString() {
|
||||
return "public static volatile " + hostingEntity.importType( getMetaType() )
|
||||
|
@ -50,15 +52,18 @@ public abstract class XmlMetaAttribute implements MetaAttribute {
|
|||
.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPropertyName() {
|
||||
return propertyName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTypeDeclaration() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public MetaEntity getHostingEntity() {
|
||||
@Override
|
||||
public Metamodel getHostingEntity() {
|
||||
return hostingEntity;
|
||||
}
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ import org.hibernate.jpamodelgen.ImportContextImpl;
|
|||
import org.hibernate.jpamodelgen.MetaModelGenerationException;
|
||||
import org.hibernate.jpamodelgen.model.ImportContext;
|
||||
import org.hibernate.jpamodelgen.model.MetaAttribute;
|
||||
import org.hibernate.jpamodelgen.model.MetaEntity;
|
||||
import org.hibernate.jpamodelgen.model.Metamodel;
|
||||
import org.hibernate.jpamodelgen.util.AccessTypeInformation;
|
||||
import org.hibernate.jpamodelgen.util.NullnessUtil;
|
||||
import org.hibernate.jpamodelgen.util.StringUtil;
|
||||
|
@ -52,7 +52,7 @@ import org.checkerframework.checker.nullness.qual.Nullable;
|
|||
*
|
||||
* @author Hardy Ferentschik
|
||||
*/
|
||||
public class XmlMetaEntity implements MetaEntity {
|
||||
public class XmlMetaEntity implements Metamodel {
|
||||
|
||||
static final Map<String, String> COLLECTIONS = new HashMap<String, String>();
|
||||
|
||||
|
@ -184,7 +184,7 @@ public class XmlMetaEntity implements MetaEntity {
|
|||
return importContext.staticImport( fqcn, member );
|
||||
}
|
||||
|
||||
public TypeElement getTypeElement() {
|
||||
public TypeElement getElement() {
|
||||
return element;
|
||||
}
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
*/
|
||||
package org.hibernate.jpamodelgen.xml;
|
||||
|
||||
import org.hibernate.jpamodelgen.model.MetaEntity;
|
||||
import org.hibernate.jpamodelgen.model.Metamodel;
|
||||
|
||||
/**
|
||||
* @author Hardy Ferentschik
|
||||
|
@ -22,7 +22,7 @@ public class XmlMetaMap extends XmlMetaCollection {
|
|||
|
||||
@Override
|
||||
public String getAttributeDeclarationString() {
|
||||
final MetaEntity hostingEntity = getHostingEntity();
|
||||
final Metamodel hostingEntity = getHostingEntity();
|
||||
return new StringBuilder().append( "public static volatile " )
|
||||
.append( hostingEntity.importType( getMetaType() ) )
|
||||
.append( "<" )
|
||||
|
|
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.jpamodelgen.test.namedquery;
|
||||
|
||||
import org.hibernate.jpamodelgen.test.util.CompilationTest;
|
||||
import org.hibernate.jpamodelgen.test.util.TestUtil;
|
||||
import org.hibernate.jpamodelgen.test.util.WithClasses;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.hibernate.jpamodelgen.test.util.TestUtil.assertMetamodelClassGeneratedFor;
|
||||
import static org.hibernate.jpamodelgen.test.util.TestUtil.assertPresenceOfNameFieldInMetamodelFor;
|
||||
|
||||
/**
|
||||
* @author Gavin King
|
||||
*/
|
||||
public class AuxiliaryTest extends CompilationTest {
|
||||
@Test
|
||||
@WithClasses({ Book.class, Main.class })
|
||||
public void testGeneratedAnnotationNotGenerated() {
|
||||
System.out.println( TestUtil.getMetaModelSourceAsString( Main.class ) );
|
||||
assertMetamodelClassGeneratedFor( Book.class );
|
||||
assertMetamodelClassGeneratedFor( Main.class );
|
||||
assertPresenceOfNameFieldInMetamodelFor(
|
||||
Main.class,
|
||||
"QUERY_BOOK_BY_TITLE",
|
||||
"Missing named query attribute."
|
||||
);
|
||||
assertPresenceOfNameFieldInMetamodelFor(
|
||||
Main.class,
|
||||
"QUERY_BOOK_BY_ISBN",
|
||||
"Missing named query attribute."
|
||||
);
|
||||
assertPresenceOfNameFieldInMetamodelFor(
|
||||
Main.class,
|
||||
"QUERY_BOOK_NATIVE_QUERY",
|
||||
"Missing named native query attribute."
|
||||
);
|
||||
assertPresenceOfNameFieldInMetamodelFor(
|
||||
Main.class,
|
||||
"MAPPING_BOOK_NATIVE_QUERY_RESULT",
|
||||
"Missing result set mapping."
|
||||
);
|
||||
assertPresenceOfNameFieldInMetamodelFor(
|
||||
Main.class,
|
||||
"PROFILE_FETCH_ONE",
|
||||
"Missing fetch profile attribute."
|
||||
);
|
||||
assertPresenceOfNameFieldInMetamodelFor(
|
||||
Main.class,
|
||||
"PROFILE_FETCH_TWO",
|
||||
"Missing fetch profile attribute."
|
||||
);
|
||||
assertPresenceOfNameFieldInMetamodelFor(
|
||||
Main.class,
|
||||
"PROFILE_DUMMY_FETCH",
|
||||
"Missing fetch profile attribute."
|
||||
);
|
||||
assertPresenceOfNameFieldInMetamodelFor(
|
||||
Main.class,
|
||||
"MAPPING_RESULT_SET_MAPPING_ONE",
|
||||
"Missing fetch profile attribute."
|
||||
);
|
||||
assertPresenceOfNameFieldInMetamodelFor(
|
||||
Main.class,
|
||||
"MAPPING_RESULT_SET_MAPPING_TWO",
|
||||
"Missing fetch profile attribute."
|
||||
);
|
||||
assertPresenceOfNameFieldInMetamodelFor(
|
||||
Main.class,
|
||||
"QUERY__SYSDATE_",
|
||||
"Missing fetch profile attribute."
|
||||
);
|
||||
assertPresenceOfNameFieldInMetamodelFor(
|
||||
Book.class,
|
||||
"GRAPH_ENTITY_GRAPH",
|
||||
"Missing fetch profile attribute."
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
package org.hibernate.jpamodelgen.test.namedquery;
|
||||
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.NamedEntityGraph;
|
||||
|
||||
@Entity
|
||||
@NamedEntityGraph(name = "entityGraph")
|
||||
public class Book {
|
||||
@Id String isbn;
|
||||
String title;
|
||||
String text;
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
package org.hibernate.jpamodelgen.test.namedquery;
|
||||
|
||||
import jakarta.persistence.NamedNativeQueries;
|
||||
import jakarta.persistence.NamedNativeQuery;
|
||||
import jakarta.persistence.NamedQueries;
|
||||
import jakarta.persistence.NamedQuery;
|
||||
import jakarta.persistence.SqlResultSetMapping;
|
||||
import jakarta.persistence.SqlResultSetMappings;
|
||||
import org.hibernate.annotations.FetchProfile;
|
||||
import org.hibernate.annotations.FetchProfiles;
|
||||
|
||||
@NamedQueries(@NamedQuery(name = "bookByIsbn", query = "from Book where isbn = :isbn"))
|
||||
@NamedQuery(name = "bookByTitle", query = "from Book where title = :title")
|
||||
@FetchProfile(name = "dummy-fetch")
|
||||
@FetchProfiles({@FetchProfile(name = "fetch.one"), @FetchProfile(name = "fetch#two")})
|
||||
@NamedNativeQuery(name = "bookNativeQuery", query = "select * from Book")
|
||||
@NamedNativeQueries(@NamedNativeQuery(name = "(sysdate)", query = "select sysdate from dual"))
|
||||
@SqlResultSetMapping(name = "bookNativeQueryResult")
|
||||
@SqlResultSetMappings({@SqlResultSetMapping(name="result set mapping one"), @SqlResultSetMapping(name = "result_set-mapping-two")})
|
||||
public class Main {
|
||||
}
|
|
@ -86,6 +86,11 @@ public class TestUtil {
|
|||
assertTrue( buildErrorString( errorString, clazz ), hasFieldInMetamodelFor( clazz, fieldName ) );
|
||||
}
|
||||
|
||||
public static void assertPresenceOfNameFieldInMetamodelFor(Class<?> clazz, String fieldName, String errorString) {
|
||||
assertTrue( buildErrorString( errorString, clazz ), hasFieldInMetamodelFor( clazz, fieldName ) );
|
||||
assertEquals(buildErrorString(errorString, clazz), getFieldFromMetamodelFor(clazz, fieldName).getType(), String.class);
|
||||
}
|
||||
|
||||
public static void assertAttributeTypeInMetaModelFor(Class<?> clazz, String fieldName, Class<?> expectedType, String errorString) {
|
||||
Field field = getFieldFromMetamodelFor( clazz, fieldName );
|
||||
assertNotNull( "Cannot find field '" + fieldName + "' in " + clazz.getName(), field );
|
||||
|
|
Loading…
Reference in New Issue