Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
HHH-8306 Added Gradle plugin to provide build time support for enhanc…
…ing entity objects.
- Loading branch information
Showing
7 changed files
with
405 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
/* | ||
* Hibernate, Relational Persistence for Idiomatic Java | ||
* | ||
* Copyright (c) 2013, Red Hat Inc. or third-party contributors as | ||
* indicated by the @author tags or express copyright attribution | ||
* statements applied by the authors. All third-party contributions are | ||
* distributed under license by Red Hat Inc. | ||
* | ||
* This copyrighted material is made available to anyone wishing to use, modify, | ||
* copy, or redistribute it subject to the terms and conditions of the GNU | ||
* Lesser General Public License, as published by the Free Software Foundation. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY | ||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | ||
* for more details. | ||
* | ||
* You should have received a copy of the GNU Lesser General Public License | ||
* along with this distribution; if not, write to: | ||
* Free Software Foundation, Inc. | ||
* 51 Franklin Street, Fifth Floor | ||
* Boston, MA 02110-1301 USA | ||
*/ | ||
apply plugin: 'groovy' | ||
apply plugin: 'maven' | ||
apply plugin: 'java' | ||
|
||
repositories { | ||
mavenCentral() | ||
} | ||
|
||
dependencies { | ||
compile group: 'org.hibernate', name: 'hibernate-core', version: '4.2.2.Final' | ||
compile group: 'org.hibernate.javax.persistence', name: 'hibernate-jpa-2.1-api', version: '1.0.0.Draft-16' | ||
compile group: 'org.javassist', name: 'javassist', version: '3.15.0-GA' | ||
compile gradleApi() | ||
compile localGroovy() | ||
} | ||
|
||
/* Available for testing locally. */ | ||
install { | ||
repositories.mavenInstaller { | ||
pom.groupId = 'org.hibernate' | ||
pom.artifactId = 'hibernate-gradle-plugin' | ||
pom.version = '0.1' | ||
} | ||
} |
66 changes: 66 additions & 0 deletions
66
...e-gradle-plugin/src/main/groovy/org/hibernate/bytecode/enhance/plugins/EnhancePlugin.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
/* | ||
* Hibernate, Relational Persistence for Idiomatic Java | ||
* | ||
* Copyright (c) 2013, Red Hat Inc. or third-party contributors as | ||
* indicated by the @author tags or express copyright attribution | ||
* statements applied by the authors. All third-party contributions are | ||
* distributed under license by Red Hat Inc. | ||
* | ||
* This copyrighted material is made available to anyone wishing to use, modify, | ||
* copy, or redistribute it subject to the terms and conditions of the GNU | ||
* Lesser General Public License, as published by the Free Software Foundation. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY | ||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | ||
* for more details. | ||
* | ||
* You should have received a copy of the GNU Lesser General Public License | ||
* along with this distribution; if not, write to: | ||
* Free Software Foundation, Inc. | ||
* 51 Franklin Street, Fifth Floor | ||
* Boston, MA 02110-1301 USA | ||
*/ | ||
package org.hibernate.bytecode.enhance.plugins; | ||
|
||
import org.gradle.api.Plugin; | ||
import org.gradle.api.Project; | ||
import org.gradle.api.Task; | ||
import org.gradle.api.plugins.BasePlugin; | ||
import org.gradle.api.plugins.JavaBasePlugin; | ||
import org.gradle.api.artifacts.Configuration; | ||
import org.gradle.api.plugins.JavaPlugin; | ||
import org.hibernate.bytecode.enhance.plugins.EnhanceTask; | ||
import org.hibernate.bytecode.enhance.plugins.EnhancePluginConvention; | ||
|
||
/** | ||
* This plugin will add Entity enhancement behaviour to the build lifecycle. | ||
* | ||
* @author Jeremy Whiting | ||
*/ | ||
public class EnhancePlugin implements Plugin<Project> { | ||
|
||
public static final String ENHANCE_TASK_NAME = "enhance"; | ||
public static final String PLUGIN_CONVENTION_NAME = "enhance"; | ||
public static final String HAPPENS_BEFORE_ENHANCE_TASK_NAME = JavaPlugin.CLASSES_TASK_NAME; | ||
public static final String HAPPENS_AFTER_ENHANCE_TASK_NAME = JavaPlugin.JAR_TASK_NAME; | ||
|
||
public void apply(Project project) { | ||
project.getLogger().debug( "Applying enhance plugin to project." ); | ||
project.getConvention().getPlugins().put( PLUGIN_CONVENTION_NAME, new EnhancePluginConvention() ); | ||
configureTask( project ); | ||
project.getLogger().debug( String.format( "DAG has been configured with enhance task dependent on [%s].", HAPPENS_BEFORE_ENHANCE_TASK_NAME ) ); | ||
} | ||
|
||
private void configureTask(Project project) { | ||
EnhanceTask enhanceTask = project.getTasks().create( ENHANCE_TASK_NAME, EnhanceTask.class ); | ||
// connect up the task in the task dependency graph | ||
final Configuration config = enhanceTask.getProject().getConfigurations().getByName( JavaPlugin.COMPILE_CONFIGURATION_NAME ); | ||
Task classesTask = project.getTasks().getByName( JavaPlugin.CLASSES_TASK_NAME ); | ||
enhanceTask.dependsOn( classesTask ); | ||
enhanceTask.mustRunAfter( HAPPENS_BEFORE_ENHANCE_TASK_NAME ); | ||
|
||
Task jarTask = project.getTasks().getByName( HAPPENS_AFTER_ENHANCE_TASK_NAME ); | ||
jarTask.dependsOn( enhanceTask ); | ||
} | ||
} |
46 changes: 46 additions & 0 deletions
46
...gin/src/main/groovy/org/hibernate/bytecode/enhance/plugins/EnhancePluginConvention.groovy
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
/* | ||
* Hibernate, Relational Persistence for Idiomatic Java | ||
* | ||
* Copyright (c) 2013, Red Hat Inc. or third-party contributors as | ||
* indicated by the @author tags or express copyright attribution | ||
* statements applied by the authors. All third-party contributions are | ||
* distributed under license by Red Hat Inc. | ||
* | ||
* This copyrighted material is made available to anyone wishing to use, modify, | ||
* copy, or redistribute it subject to the terms and conditions of the GNU | ||
* Lesser General Public License, as published by the Free Software Foundation. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY | ||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | ||
* for more details. | ||
* | ||
* You should have received a copy of the GNU Lesser General Public License | ||
* along with this distribution; if not, write to: | ||
* Free Software Foundation, Inc. | ||
* 51 Franklin Street, Fifth Floor | ||
* Boston, MA 02110-1301 USA | ||
*/ | ||
package org.hibernate.bytecode.enhance.plugins | ||
|
||
/** | ||
* Convention object for plugin. | ||
*/ | ||
class EnhancePluginConvention { | ||
|
||
def contexts = [] | ||
|
||
public EnhancePluginConvention() { | ||
contexts.add('org.hibernate.bytecode.enhance.contexts.AssociationReference') | ||
} | ||
|
||
def add(final String fullyQualifiedClassName) { | ||
contexts.add(fullyQualifiedClassName); | ||
} | ||
List getContexts() { | ||
return contexts | ||
} | ||
def clear() { | ||
contexts.clear(); | ||
} | ||
} |
110 changes: 110 additions & 0 deletions
110
...e-gradle-plugin/src/main/groovy/org/hibernate/bytecode/enhance/plugins/EnhanceTask.groovy
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
/* | ||
* Hibernate, Relational Persistence for Idiomatic Java | ||
* | ||
* Copyright (c) 2013, Red Hat Inc. or third-party contributors as | ||
* indicated by the @author tags or express copyright attribution | ||
* statements applied by the authors. All third-party contributions are | ||
* distributed under license by Red Hat Inc. | ||
* | ||
* This copyrighted material is made available to anyone wishing to use, modify, | ||
* copy, or redistribute it subject to the terms and conditions of the GNU | ||
* Lesser General Public License, as published by the Free Software Foundation. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY | ||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | ||
* for more details. | ||
* | ||
* You should have received a copy of the GNU Lesser General Public License | ||
* along with this distribution; if not, write to: | ||
* Free Software Foundation, Inc. | ||
* 51 Franklin Street, Fifth Floor | ||
* Boston, MA 02110-1301 USA | ||
*/ | ||
package org.hibernate.bytecode.enhance.plugins | ||
|
||
import org.hibernate.bytecode.enhance.spi.Enhancer | ||
import javassist.ClassPool | ||
import javassist.CtClass | ||
import javassist.CtField | ||
import javax.persistence.Transient | ||
import javax.persistence.Entity | ||
import java.io.FileInputStream | ||
import java.io.FileOutputStream | ||
import org.gradle.api.DefaultTask | ||
import org.gradle.api.plugins.Convention | ||
import org.gradle.api.tasks.TaskAction | ||
import org.gradle.api.file.FileTree | ||
|
||
/** | ||
* Plugin to enhance Entities using the context(s) to determine | ||
* which to apply. | ||
* @author Jeremy Whiting | ||
*/ | ||
public class EnhanceTask extends DefaultTask { | ||
|
||
public EnhanceTask() { | ||
super() | ||
setDescription('Enhances Entity classes for efficient association referencing.') | ||
} | ||
|
||
@TaskAction | ||
def enhance () { | ||
logger.info( 'enhance task started') | ||
ext.pool = new ClassPool(false) | ||
EnhancePluginConvention convention = (EnhancePluginConvention)project.getConvention().getPlugins().get( EnhancePlugin.PLUGIN_CONVENTION_NAME) | ||
convention.contexts.each( | ||
{ String context -> | ||
ext.enhancer = new Enhancer(EnhanceTask.class.getClassLoader().loadClass(context).newInstance()) | ||
FileTree tree = project.fileTree(dir: project.sourceSets.main.output.classesDir) | ||
tree.include '**/*.class' | ||
tree.each( | ||
{ File file -> | ||
final byte[] enhancedBytecode; | ||
InputStream is = null; | ||
CtClass clas = null; | ||
try { | ||
is = new FileInputStream(file.toString()) | ||
clas =ext.pool.makeClass(is) | ||
if (!clas.hasAnnotation(Entity.class)){ | ||
logger.debug("Class $file not an annotated Entity class. skipping...") | ||
} else { | ||
enhancedBytecode = ext.enhancer.enhance( clas.getName(), clas.toBytecode() ); | ||
} | ||
} | ||
catch (Exception e) { | ||
logger.error( "Unable to enhance class [${file.toString()}]", e ) | ||
return | ||
} finally { | ||
try { | ||
if (null != is) is.close(); | ||
} finally{} | ||
} | ||
if (null != enhancedBytecode){ | ||
if ( file.delete() ) { | ||
if ( ! file.createNewFile() ) { | ||
logger.error( "Unable to recreate class file [" + clas.getName() + "]") | ||
} | ||
} | ||
else { | ||
logger.error( "Unable to delete class file [" + clas.getName() + "]") | ||
} | ||
FileOutputStream outputStream = new FileOutputStream( file, false ) | ||
try { | ||
outputStream.write( enhancedBytecode ) | ||
outputStream.flush() | ||
} | ||
finally { | ||
try { | ||
if (outputStream != null) outputStream.close() | ||
clas.detach()//release memory | ||
} | ||
catch ( IOException ignore) { | ||
} | ||
} | ||
} | ||
}) | ||
}) | ||
logger.info( 'enhance task finished') | ||
} | ||
} |
57 changes: 57 additions & 0 deletions
57
...le-plugin/src/main/java/org/hibernate/bytecode/enhance/contexts/AssociationReference.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
/* | ||
* Hibernate, Relational Persistence for Idiomatic Java | ||
* | ||
* Copyright (c) 2013, Red Hat Inc. or third-party contributors as | ||
* indicated by the @author tags or express copyright attribution | ||
* statements applied by the authors. All third-party contributions are | ||
* distributed under license by Red Hat Inc. | ||
* | ||
* This copyrighted material is made available to anyone wishing to use, modify, | ||
* copy, or redistribute it subject to the terms and conditions of the GNU | ||
* Lesser General Public License, as published by the Free Software Foundation. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY | ||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | ||
* for more details. | ||
* | ||
* You should have received a copy of the GNU Lesser General Public License | ||
* along with this distribution; if not, write to: | ||
* Free Software Foundation, Inc. | ||
* 51 Franklin Street, Fifth Floor | ||
* Boston, MA 02110-1301 USA | ||
*/ | ||
package org.hibernate.bytecode.enhance.contexts; | ||
|
||
import javassist.CtClass; | ||
import javassist.CtField; | ||
|
||
public class AssociationReference extends BaseContext { | ||
|
||
private ClassLoader overridden; | ||
|
||
public ClassLoader getLoadingClassLoader() { | ||
if ( null == this.overridden ) { | ||
return getClass().getClassLoader(); | ||
} | ||
else { | ||
return this.overridden; | ||
} | ||
} | ||
|
||
public void setClassLoader(ClassLoader loader) { | ||
this.overridden = loader; | ||
} | ||
|
||
public boolean isEntityClass(CtClass classDescriptor) { | ||
return true; | ||
} | ||
|
||
public boolean hasLazyLoadableAttributes(CtClass classDescriptor) { | ||
return true; | ||
} | ||
|
||
public boolean isLazyLoadable(CtField field) { | ||
return true; | ||
} | ||
} |
Oops, something went wrong.