Author: hardy.ferentschik
Date: 2010-10-06 07:16:11 -0400 (Wed, 06 Oct 2010)
New Revision: 20777
Added:
jpamodelgen/trunk/src/test/java/org/hibernate/jpamodelgen/test/separatecompilationunits/
jpamodelgen/trunk/src/test/java/org/hibernate/jpamodelgen/test/separatecompilationunits/Entity.java
jpamodelgen/trunk/src/test/java/org/hibernate/jpamodelgen/test/separatecompilationunits/SeparateCompilationUnitsTest.java
jpamodelgen/trunk/src/test/java/org/hibernate/jpamodelgen/test/separatecompilationunits/superclass/
jpamodelgen/trunk/src/test/java/org/hibernate/jpamodelgen/test/separatecompilationunits/superclass/MappedSuperclass.java
Modified:
jpamodelgen/trunk/src/main/java/org/hibernate/jpamodelgen/ClassWriter.java
Log:
METAGEN-35 Actual code changes and tests for the issue.
Modified: jpamodelgen/trunk/src/main/java/org/hibernate/jpamodelgen/ClassWriter.java
===================================================================
--- jpamodelgen/trunk/src/main/java/org/hibernate/jpamodelgen/ClassWriter.java 2010-10-05
14:08:57 UTC (rev 20776)
+++ jpamodelgen/trunk/src/main/java/org/hibernate/jpamodelgen/ClassWriter.java 2010-10-06
11:16:11 UTC (rev 20777)
@@ -31,6 +31,8 @@
import javax.lang.model.type.DeclaredType;
import javax.lang.model.type.TypeKind;
import javax.lang.model.type.TypeMirror;
+import javax.persistence.Entity;
+import javax.persistence.MappedSuperclass;
import javax.tools.Diagnostic;
import javax.tools.FileObject;
@@ -38,9 +40,13 @@
import org.hibernate.jpamodelgen.model.MetaEntity;
/**
+ * Helper class to write the actual meta model class using the {@link
javax.annotation.processing.Filer} API.
+ *
* @author Emmanuel Bernard
+ * @author Hardy Ferentschik
*/
public final class ClassWriter {
+ private static final String META_MODEL_CLASS_NAME_SUFFIX = "_";
private ClassWriter() {
}
@@ -51,7 +57,7 @@
StringBuffer body = generateBody( entity, context );
FileObject fo = context.getProcessingEnvironment().getFiler().createSourceFile(
- metaModelPackage + "." + entity.getSimpleName() + "_"
+ getFullyQualifiedClassName( entity, metaModelPackage )
);
OutputStream os = fo.openOutputStream();
PrintWriter pw = new PrintWriter( os );
@@ -63,7 +69,6 @@
pw.flush();
pw.close();
-
}
catch ( FilerException filerEx ) {
context.logMessage(
@@ -87,15 +92,14 @@
* @return body content
*/
private static StringBuffer generateBody(MetaEntity entity, Context context) {
-
StringWriter sw = new StringWriter();
PrintWriter pw = null;
try {
pw = new PrintWriter( sw );
if ( context.isAddGeneratedAnnotation() ) {
- pw.println( "@" + entity.importType( Generated.class.getName() ) +
"(\"JPA MetaModel for " + entity.getQualifiedName() + "\")"
);
+ pw.println( writeGeneratedAnnotation( entity ) );
}
- pw.println( "@" + entity.importType(
"javax.persistence.metamodel.StaticMetamodel" ) + "(" +
entity.getSimpleName() + ".class)" );
+ pw.println( writeStaticMetaModelAnnotation( entity ) );
printClassDeclaration( entity, pw, context );
pw.println();
List<MetaAttribute> members = entity.getMembers();
@@ -114,19 +118,62 @@
}
private static void printClassDeclaration(MetaEntity entity, PrintWriter pw, Context
context) {
- pw.print( "public abstract class " + entity.getSimpleName() + "_"
);
+ pw.print( "public abstract class " + entity.getSimpleName() +
META_MODEL_CLASS_NAME_SUFFIX );
final TypeMirror superClass = entity.getTypeElement().getSuperclass();
//superclass of Object is of NoType which returns some other kind
if ( 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 ( context.containsMetaEntity( superClassName )
- || context.containsMetaEmbeddable( superClassName ) ) {
- pw.print( " extends " + superClassName + "_" );
+ final Element superClassElement = ( (DeclaredType) superClass ).asElement();
+ String superClassName = ( (TypeElement) superClassElement
).getQualifiedName().toString();
+ if ( extendsSuperMetaModel( superClassElement, entity.isMetaComplete(), context ) ) {
+ pw.print( " extends " + superClassName + META_MODEL_CLASS_NAME_SUFFIX );
}
}
pw.println( " {" );
}
+
+ /**
+ * Checks whether this metamodel class needs to extend another metamodel class.
+ * This methods checks whether the processor has generated a metamodel class for the
super class, but it also
+ * allows for the possibility that the metamodel class was generated in a previous
compilation (eg it could be
+ * part of a separate jar. See also METAGEN-35).
+ *
+ * @param superClassElement the super class element
+ * @param entityMetaComplete flag indicating if the entity for which the metamodel
should be generarted is metamodel
+ * complete. If so we cannot use reflection to decide whether we have to add the extend
clause
+ * @param context the execution context
+ *
+ * @return {@code true} in case there is super class meta model to extend from {@code
false} otherwise.
+ */
+ private static boolean extendsSuperMetaModel(Element superClassElement, boolean
entityMetaComplete, Context context) {
+ // if we processed the superclass in the same run we definitely need to extend
+ String superClassName = ( (TypeElement) superClassElement
).getQualifiedName().toString();
+ if ( context.containsMetaEntity( superClassName )
+ || context.containsMetaEmbeddable( superClassName ) ) {
+ return true;
+ }
+
+ // to allow for the case that the metamodel class for the super entity is for example
contained in another
+ // jar file we use reflection. However, we need to consider the fact that there is xml
configuration
+ // and annotations should be ignored
+ if ( !entityMetaComplete && ( superClassElement.getAnnotation( Entity.class )
!= null
+ || superClassElement.getAnnotation( MappedSuperclass.class ) != null ) ) {
+ return true;
+ }
+
+ return false;
+ }
+
+ private static String getFullyQualifiedClassName(MetaEntity entity, String
metaModelPackage) {
+ return metaModelPackage + "." + entity.getSimpleName() +
META_MODEL_CLASS_NAME_SUFFIX;
+ }
+
+ private static String writeGeneratedAnnotation(MetaEntity entity) {
+ return "@" + entity.importType( Generated.class.getName() ) +
"(\"JPA MetaModel for " + entity.getQualifiedName() +
"\")";
+ }
+
+ private static String writeStaticMetaModelAnnotation(MetaEntity entity) {
+ return "@" + entity.importType(
"javax.persistence.metamodel.StaticMetamodel" ) + "(" +
entity.getSimpleName() + ".class)";
+ }
}
Added:
jpamodelgen/trunk/src/test/java/org/hibernate/jpamodelgen/test/separatecompilationunits/Entity.java
===================================================================
---
jpamodelgen/trunk/src/test/java/org/hibernate/jpamodelgen/test/separatecompilationunits/Entity.java
(rev 0)
+++
jpamodelgen/trunk/src/test/java/org/hibernate/jpamodelgen/test/separatecompilationunits/Entity.java 2010-10-06
11:16:11 UTC (rev 20777)
@@ -0,0 +1,31 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// $Id:$
+package org.hibernate.jpamodelgen.test.separatecompilationunits;
+
+import
org.hibernate.jpamodelgen.test.separatecompilationunits.superclass.MappedSuperclass;
+
+/**
+ * @author Hardy Ferentschik
+ */
+(a)javax.persistence.Entity
+public class Entity extends MappedSuperclass {
+ private String name;
+}
+
+
Property changes on:
jpamodelgen/trunk/src/test/java/org/hibernate/jpamodelgen/test/separatecompilationunits/Entity.java
___________________________________________________________________
Name: svn:keywords
+ Id
Added:
jpamodelgen/trunk/src/test/java/org/hibernate/jpamodelgen/test/separatecompilationunits/SeparateCompilationUnitsTest.java
===================================================================
---
jpamodelgen/trunk/src/test/java/org/hibernate/jpamodelgen/test/separatecompilationunits/SeparateCompilationUnitsTest.java
(rev 0)
+++
jpamodelgen/trunk/src/test/java/org/hibernate/jpamodelgen/test/separatecompilationunits/SeparateCompilationUnitsTest.java 2010-10-06
11:16:11 UTC (rev 20777)
@@ -0,0 +1,68 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// $Id$
+
+package org.hibernate.jpamodelgen.test.separatecompilationunits;
+
+import java.io.File;
+import java.util.List;
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import org.hibernate.jpamodelgen.test.util.CompilationTest;
+
+import static org.hibernate.jpamodelgen.test.util.TestUtil.getMetaModelSourceAsString;
+import static org.testng.Assert.assertTrue;
+
+/**
+ * @author Hardy Ferentschik
+ * @see METAGEN-35
+ */
+public class SeparateCompilationUnitsTest extends CompilationTest {
+ @Test
+ public void testInheritance() throws Exception {
+ // need to work with the source file. Entity_.class won't get generated, because
the mapped superclass
+ // will not be on the classpath
+ String entityMetaModel = getMetaModelSourceAsString( Entity.class );
+ assertTrue(
+ entityMetaModel.contains(
+ "extends
org.hibernate.jpamodelgen.test.separatecompilationunits.superclass.MappedSuperclass"
+ )
+ );
+ }
+
+ @Override
+ @BeforeClass
+ // override compileAllTestEntities to compile the mapped super class explicitly
+ protected void compileAllTestEntities() throws Exception {
+ String superClassPackageName = getPackageNameOfCurrentTest() +
".superclass";
+ List<File> sourceFiles = getCompilationUnits(
+ CompilationTest.getSourceBaseDir(), superClassPackageName
+ );
+ compile( sourceFiles, superClassPackageName );
+
+ sourceFiles = getCompilationUnits( getSourceBaseDir(), getPackageNameOfCurrentTest()
);
+ compile( sourceFiles, getPackageNameOfCurrentTest() );
+ }
+
+ @Override
+ protected String getPackageNameOfCurrentTest() {
+ return SeparateCompilationUnitsTest.class.getPackage().getName();
+ }
+}
Property changes on:
jpamodelgen/trunk/src/test/java/org/hibernate/jpamodelgen/test/separatecompilationunits/SeparateCompilationUnitsTest.java
___________________________________________________________________
Name: svn:keywords
+ Id
Added:
jpamodelgen/trunk/src/test/java/org/hibernate/jpamodelgen/test/separatecompilationunits/superclass/MappedSuperclass.java
===================================================================
---
jpamodelgen/trunk/src/test/java/org/hibernate/jpamodelgen/test/separatecompilationunits/superclass/MappedSuperclass.java
(rev 0)
+++
jpamodelgen/trunk/src/test/java/org/hibernate/jpamodelgen/test/separatecompilationunits/superclass/MappedSuperclass.java 2010-10-06
11:16:11 UTC (rev 20777)
@@ -0,0 +1,32 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// $Id:$
+package org.hibernate.jpamodelgen.test.separatecompilationunits.superclass;
+
+import javax.persistence.Id;
+
+/**
+ * @author Hardy Ferentschik
+ */
+(a)javax.persistence.MappedSuperclass
+public class MappedSuperclass {
+ @Id
+ private long id;
+}
+
+
Property changes on:
jpamodelgen/trunk/src/test/java/org/hibernate/jpamodelgen/test/separatecompilationunits/superclass/MappedSuperclass.java
___________________________________________________________________
Name: svn:keywords
+ Id