HHH-6016 - Migrate version injection plugin to Gradle
This commit is contained in:
parent
4f188a934c
commit
671ef3accd
|
@ -10,14 +10,22 @@ repositories {
|
|||
|
||||
|
||||
dependencies {
|
||||
// common
|
||||
compile gradleApi()
|
||||
compile localGroovy()
|
||||
compile 'org.slf4j:slf4j-api:1.6.0'
|
||||
compile 'org.apache.ant:ant:1.7.0'
|
||||
compile 'org.apache.maven:maven-ant-tasks:2.1.0'
|
||||
|
||||
// needed?
|
||||
compile 'org.apache.maven.wagon:wagon-http:1.0-beta-6'
|
||||
|
||||
// upload-auth plugin
|
||||
compile 'dom4j:dom4j:1.6.1@jar'
|
||||
|
||||
// injection plugin
|
||||
compile 'javassist:javassist:3.12.0.GA'
|
||||
|
||||
groovy localGroovy()
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2011, 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.build.gradle.inject;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class Injection {
|
||||
private final String expression;
|
||||
private List<TargetMember> targetMembers = new ArrayList<TargetMember>();
|
||||
|
||||
public Injection(String expression) {
|
||||
this.expression = expression;
|
||||
}
|
||||
|
||||
public String getExpression() {
|
||||
return expression;
|
||||
}
|
||||
|
||||
public void into(String className, String member) {
|
||||
into( new TargetMember( className, member ) );
|
||||
}
|
||||
|
||||
public void into(TargetMember targetMember) {
|
||||
targetMembers.add( targetMember );
|
||||
}
|
||||
|
||||
public Iterable<TargetMember> getTargetMembers() {
|
||||
return targetMembers;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,252 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2011, 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.build.gradle.inject;
|
||||
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javassist.ClassPool;
|
||||
import javassist.CtClass;
|
||||
import javassist.CtField;
|
||||
import javassist.CtMethod;
|
||||
import javassist.LoaderClassPath;
|
||||
import javassist.Modifier;
|
||||
import javassist.NotFoundException;
|
||||
import javassist.bytecode.ClassFile;
|
||||
import javassist.bytecode.ConstantAttribute;
|
||||
import javassist.bytecode.FieldInfo;
|
||||
import org.gradle.api.Action;
|
||||
import org.gradle.api.Project;
|
||||
import org.gradle.api.plugins.JavaPluginConvention;
|
||||
import org.gradle.api.tasks.SourceSet;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class InjectionAction implements Action {
|
||||
private static final Logger log = LoggerFactory.getLogger( InjectionAction.class );
|
||||
|
||||
private final Project project;
|
||||
|
||||
private List<Injection> injections = new ArrayList<Injection>();
|
||||
|
||||
private LoaderClassPath loaderClassPath;
|
||||
private ClassPool classPool;
|
||||
|
||||
public InjectionAction(Project project) {
|
||||
this.project = project;
|
||||
}
|
||||
|
||||
void addInjection(Injection injection) {
|
||||
injections.add( injection );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Object o) {
|
||||
final ClassLoader runtimeScopeClassLoader = buildRuntimeScopeClassLoader();
|
||||
|
||||
loaderClassPath = new LoaderClassPath( runtimeScopeClassLoader );
|
||||
classPool = new ClassPool( true );
|
||||
classPool.appendClassPath( loaderClassPath );
|
||||
|
||||
try {
|
||||
performInjections();
|
||||
}
|
||||
finally {
|
||||
loaderClassPath.close();
|
||||
}
|
||||
}
|
||||
|
||||
private ClassLoader buildRuntimeScopeClassLoader() {
|
||||
final ArrayList<URL> classPathUrls = new ArrayList<URL>();
|
||||
final SourceSet mainSourceSet = project
|
||||
.getConvention()
|
||||
.getPlugin( JavaPluginConvention.class )
|
||||
.getSourceSets()
|
||||
.findByName( SourceSet.MAIN_SOURCE_SET_NAME );
|
||||
for ( File file : mainSourceSet.getRuntimeClasspath() ) {
|
||||
try {
|
||||
classPathUrls.add( file.toURI().toURL() );
|
||||
}
|
||||
catch (MalformedURLException e) {
|
||||
throw new InjectionException( "Could not determine artifact URL [" + file.getPath() + "]", e );
|
||||
}
|
||||
}
|
||||
return new URLClassLoader( classPathUrls.toArray( new URL[classPathUrls.size()] ), getClass().getClassLoader() );
|
||||
}
|
||||
|
||||
private void performInjections() {
|
||||
for ( Injection injection : injections ) {
|
||||
for ( TargetMember targetMember : injection.getTargetMembers() ) {
|
||||
resolveInjectionTarget( targetMember ).inject( injection.getExpression() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private InjectionTarget resolveInjectionTarget(TargetMember targetMember) {
|
||||
try {
|
||||
final CtClass ctClass = classPool.get( targetMember.getClassName() );
|
||||
// see if it is a field...
|
||||
try {
|
||||
CtField field = ctClass.getField( targetMember.getMemberName() );
|
||||
return new FieldInjectionTarget( targetMember, ctClass, field );
|
||||
}
|
||||
catch( NotFoundException ignore ) {
|
||||
}
|
||||
|
||||
// see if it is a method...
|
||||
for ( CtMethod method : ctClass.getMethods() ) {
|
||||
if ( method.getName().equals( targetMember.getMemberName() ) ) {
|
||||
return new MethodInjectionTarget( targetMember, ctClass, method );
|
||||
}
|
||||
}
|
||||
|
||||
// finally throw an exception
|
||||
throw new InjectionException( "Unknown member [" + targetMember.getQualifiedName() + "]" );
|
||||
}
|
||||
catch ( Throwable e ) {
|
||||
throw new InjectionException( "Unable to resolve class [" + targetMember.getClassName() + "]", e );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Strategy for performing an injection
|
||||
*/
|
||||
private static interface InjectionTarget {
|
||||
/**
|
||||
* Inject the given value per this target's strategy.
|
||||
*
|
||||
* @param value The value to inject.
|
||||
*
|
||||
* @throws org.hibernate.build.gradle.inject.InjectionException Indicates a problem performing the injection.
|
||||
*/
|
||||
public void inject(String value);
|
||||
}
|
||||
|
||||
private abstract class BaseInjectionTarget implements InjectionTarget {
|
||||
@SuppressWarnings( {"UnusedDeclaration"})
|
||||
private final TargetMember targetMember;
|
||||
private final CtClass ctClass;
|
||||
private final File classFileLocation;
|
||||
|
||||
protected BaseInjectionTarget(TargetMember targetMember, CtClass ctClass) {
|
||||
this.targetMember = targetMember;
|
||||
this.ctClass = ctClass;
|
||||
try {
|
||||
classFileLocation = new File( loaderClassPath.find( targetMember.getClassName() ).toURI() );
|
||||
}
|
||||
catch ( Throwable e ) {
|
||||
throw new InjectionException( "Unable to resolve class file path", e );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void inject(String value) {
|
||||
doInjection( value );
|
||||
writeOutChanges();
|
||||
}
|
||||
|
||||
protected abstract void doInjection(String value);
|
||||
|
||||
protected void writeOutChanges() {
|
||||
log.info( "writing injection changes back [" + classFileLocation.getAbsolutePath() + "]" );
|
||||
long timeStamp = classFileLocation.lastModified();
|
||||
ClassFile classFile = ctClass.getClassFile();
|
||||
classFile.compact();
|
||||
try {
|
||||
DataOutputStream out = new DataOutputStream( new BufferedOutputStream( new FileOutputStream( classFileLocation ) ) );
|
||||
try {
|
||||
|
||||
classFile.write( out );
|
||||
out.flush();
|
||||
if ( ! classFileLocation.setLastModified( System.currentTimeMillis() ) ) {
|
||||
log.info( "Unable to manually update class file timestamp" );
|
||||
}
|
||||
}
|
||||
finally {
|
||||
out.close();
|
||||
classFileLocation.setLastModified( timeStamp );
|
||||
}
|
||||
}
|
||||
catch ( IOException e ) {
|
||||
throw new InjectionException( "Unable to write out modified class file", e );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class FieldInjectionTarget extends BaseInjectionTarget {
|
||||
private final CtField ctField;
|
||||
|
||||
private FieldInjectionTarget(TargetMember targetMember, CtClass ctClass, CtField ctField) {
|
||||
super( targetMember, ctClass );
|
||||
this.ctField = ctField;
|
||||
if ( ! Modifier.isStatic( ctField.getModifiers() ) ) {
|
||||
throw new InjectionException( "Field is not static [" + targetMember.getQualifiedName() + "]" );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doInjection(String value) {
|
||||
final FieldInfo ctFieldInfo = ctField.getFieldInfo();
|
||||
|
||||
ctFieldInfo.addAttribute(
|
||||
new ConstantAttribute(
|
||||
ctFieldInfo.getConstPool(),
|
||||
ctFieldInfo.getConstPool().addStringInfo( value )
|
||||
)
|
||||
);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private class MethodInjectionTarget extends BaseInjectionTarget {
|
||||
private final CtMethod ctMethod;
|
||||
|
||||
private MethodInjectionTarget(TargetMember targetMember, CtClass ctClass, CtMethod ctMethod) {
|
||||
super( targetMember, ctClass );
|
||||
this.ctMethod = ctMethod;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doInjection(String value) {
|
||||
try {
|
||||
ctMethod.setBody( "{return \"" + value + "\";}" );
|
||||
}
|
||||
catch ( Throwable t ) {
|
||||
throw new InjectionException( "Unable to replace method body", t );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2010, Red Hat Inc. or third-party contributors as
|
||||
* Copyright (c) 2011, 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.
|
||||
|
@ -21,22 +21,17 @@
|
|||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
// $Id$
|
||||
|
||||
package org.hibernate.cfg.annotations;
|
||||
|
||||
package org.hibernate.build.gradle.inject;
|
||||
|
||||
/**
|
||||
* @author Emmanuel Bernard
|
||||
* @deprecated Use {@link org.hibernate.Version} instead
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
@Deprecated
|
||||
public class Version {
|
||||
public static String getVersionString() {
|
||||
return org.hibernate.Version.getVersionString();
|
||||
public class InjectionException extends RuntimeException {
|
||||
public InjectionException(String message) {
|
||||
super( message );
|
||||
}
|
||||
|
||||
public static void touch() {
|
||||
public InjectionException(String message, Throwable cause) {
|
||||
super( message, cause );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2011, 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.build.gradle.inject;
|
||||
|
||||
import org.gradle.api.Plugin;
|
||||
import org.gradle.api.Project;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class InjectionPlugin implements Plugin<Project> {
|
||||
|
||||
@Override
|
||||
public void apply(Project project) {
|
||||
final InjectionAction injectionAction = new InjectionAction( project );
|
||||
|
||||
// For now, just do what Hibernate needs rather than a full blown "convention" object
|
||||
Injection versionInjection = new Injection( project.getVersion().toString() );
|
||||
versionInjection.into( "org.hibernate.Version", "getVersionString" );
|
||||
injectionAction.addInjection( versionInjection );
|
||||
project.getTasks().findByName( "compileJava" ).doLast( injectionAction );
|
||||
}
|
||||
|
||||
}
|
|
@ -1,9 +1,10 @@
|
|||
// $Id$
|
||||
/*
|
||||
* Copyright (c) 2009, Red Hat Middleware LLC or third-party contributors as
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2011, 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 Middleware LLC.
|
||||
* 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
|
||||
|
@ -20,27 +21,30 @@
|
|||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
//$Id$
|
||||
package org.hibernate.ejb;
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
package org.hibernate.build.gradle.inject;
|
||||
|
||||
/**
|
||||
* @author Emmanuel Bernard
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class Version {
|
||||
public class TargetMember {
|
||||
private final String className;
|
||||
private final String memberName;
|
||||
|
||||
public static final EntityManagerLogger LOG = Logger.getMessageLogger(EntityManagerLogger.class, Version.class.getName());
|
||||
|
||||
public static String getVersionString() {
|
||||
return "[WORKING]";
|
||||
public TargetMember(String className, String memberName) {
|
||||
this.className = className;
|
||||
this.memberName = memberName;
|
||||
}
|
||||
|
||||
static {
|
||||
LOG.entityManagerVersion(getVersionString());
|
||||
public String getClassName() {
|
||||
return className;
|
||||
}
|
||||
|
||||
public static void touch() {
|
||||
public String getMemberName() {
|
||||
return memberName;
|
||||
}
|
||||
|
||||
public String getQualifiedName() {
|
||||
return getClassName() + "#" + getMemberName();
|
||||
}
|
||||
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
apply plugin: 'java'
|
||||
apply plugin: 'antlr'
|
||||
apply plugin: org.hibernate.build.gradle.inject.InjectionPlugin
|
||||
|
||||
dependencies {
|
||||
compile( libraries.commons_collections )
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2009, Red Hat Middleware LLC or third-party contributors as
|
||||
* Copyright (c) 2009-2011, 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 Middleware LLC.
|
||||
* 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
|
||||
|
@ -23,7 +23,6 @@
|
|||
*/
|
||||
package org.hibernate;
|
||||
|
||||
|
||||
/**
|
||||
* Information about the Hibernate version.
|
||||
*
|
||||
|
@ -34,6 +33,7 @@ public class Version {
|
|||
return "[WORKING]";
|
||||
}
|
||||
|
||||
|
||||
public static void main(String[] args) {
|
||||
System.out.println( "Hibernate version " + getVersionString() );
|
||||
}
|
||||
|
|
|
@ -137,10 +137,6 @@ public class Ejb3Configuration implements Serializable, Referenceable {
|
|||
}
|
||||
}
|
||||
|
||||
static {
|
||||
Version.touch();
|
||||
}
|
||||
|
||||
private String persistenceUnitName;
|
||||
private String cfgXmlResource;
|
||||
|
||||
|
|
Loading…
Reference in New Issue