[hibernate-commits] Hibernate SVN: r19845 - core/branches/gradle2/buildSrc/src/main/java/org/hibernate/gradle/testing/database.

hibernate-commits at lists.jboss.org hibernate-commits at lists.jboss.org
Mon Jun 28 15:43:57 EDT 2010


Author: steve.ebersole at jboss.com
Date: 2010-06-28 15:43:57 -0400 (Mon, 28 Jun 2010)
New Revision: 19845

Added:
   core/branches/gradle2/buildSrc/src/main/java/org/hibernate/gradle/testing/database/IvyXmlDependency.java
Modified:
   core/branches/gradle2/buildSrc/src/main/java/org/hibernate/gradle/testing/database/DatabaseMatrixPlugin.java
Log:
allow matrix.gradle file to define database testing dependencies

Modified: core/branches/gradle2/buildSrc/src/main/java/org/hibernate/gradle/testing/database/DatabaseMatrixPlugin.java
===================================================================
--- core/branches/gradle2/buildSrc/src/main/java/org/hibernate/gradle/testing/database/DatabaseMatrixPlugin.java	2010-06-28 18:47:57 UTC (rev 19844)
+++ core/branches/gradle2/buildSrc/src/main/java/org/hibernate/gradle/testing/database/DatabaseMatrixPlugin.java	2010-06-28 19:43:57 UTC (rev 19845)
@@ -2,12 +2,13 @@
 
 import java.io.File;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 
+import groovy.lang.Closure;
 import org.gradle.api.Plugin;
 import org.gradle.api.Project;
 import org.gradle.api.artifacts.Configuration;
-import org.gradle.api.file.FileCollection;
 import org.gradle.api.internal.artifacts.dependencies.DefaultSelfResolvingDependency;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -47,10 +48,57 @@
 		}
 	}
 
+	private static final String MATRIX_NODE_CONVENTION_KEY = "matrixNode";
+	private static final String MATRIX_BUILD_FILE = "matrix.gradle";
+	private static final String IVY_XML_FILE = "ivy.xml";
+
 	private void applyPossibleDatabaseDirectory(final File databaseDir) {
 		final String databaseName = databaseDir.getName();
 		log.debug( "Checking potential database directory : {}", databaseName );
 
+		MatrixNode node = null;
+
+		// 3 types of support here:
+		//		1) directory contains a file named 'matrix.gradle'
+		// 		2) directory contains a file named 'ivy.xml'
+		//		3) directory contains a sub-directory named 'jdbc' containing the driver artifacts
+
+		final File matrixFile = new File( databaseDir, MATRIX_BUILD_FILE );
+		if ( matrixFile.exists() && matrixFile.isFile() ) {
+			// (1) we found the 'matrix.gradle' file
+			node = prepareFromGradleFile( matrixFile );
+		}
+		else {
+			final File ivyXmlFile = new File( databaseDir, IVY_XML_FILE );
+			if ( ivyXmlFile.exists() && ivyXmlFile.isFile() ) {
+				// (2) we found the 'ivy.xml' file
+				node = prepareFromIvyXmlFile( ivyXmlFile );
+			}
+			else {
+				final File jdbcDir = new File( databaseDir, "jdbc" );
+				if ( jdbcDir.exists() && jdbcDir.isDirectory() ) {
+					node = prepareFromJdbcDir( jdbcDir );
+				}
+			}
+		}
+
+		if ( node == null ) {
+			log.info( "" );
+			return;
+		}
+
+		final File resourcesDir = new File( matrixFile.getParentFile(), "resources" );
+		if ( resourcesDir.isDirectory() && resourcesDir.exists() ) {
+			node.getTestingRuntimeConfiguration().addDependency(
+					new DefaultSelfResolvingDependency( project.files( resourcesDir ) )
+			);
+		}
+
+		matrixNodes.add( node );
+
+
+
+
 		final Configuration configuration = prepareJdbcDependencies( databaseDir );
 		if ( configuration == null ) {
 			return;
@@ -58,28 +106,128 @@
 		configuration.setVisible( true );
 		configuration.setDescription( "The [" + databaseName + "] JDBC dependency configuration" );
 
-		final File resourcesDir = new File( databaseDir, "resources" );
-		if ( resourcesDir.isDirectory() && resourcesDir.exists() ) {
-			configuration.addDependency(
-					new DefaultSelfResolvingDependency( project.files( resourcesDir ) )
+
+	}
+
+	private MatrixNode prepareFromGradleFile(File matrixFile) {
+		MatrixDotGradleMatrixNodeImpl matrixNode = new MatrixDotGradleMatrixNodeImpl( matrixFile.getParentFile().getName() );
+		MatrixDotGradleMatrixNodeConvention convention = new MatrixDotGradleMatrixNodeConvention( matrixNode );
+		project.getConvention().getPlugins().put( MATRIX_NODE_CONVENTION_KEY, convention );
+		try {
+			project.apply( Collections.singletonMap( "from", matrixFile ) );
+		}
+		finally {
+			project.getConvention().getPlugins().remove( MATRIX_NODE_CONVENTION_KEY );
+		}
+		return matrixNode;
+	}
+
+	/**
+	 * {@link MatrixNode} implementation for handling 'matrix.gradle' files
+	 */
+	private class MatrixDotGradleMatrixNodeImpl implements MatrixNode {
+		private final String name;
+		private final Configuration jdbcDependencies;
+		private Jdk jdk;
+
+		public MatrixDotGradleMatrixNodeImpl(String name) {
+			this.name = name;
+			this.jdbcDependencies = prepareConfiguration( name );
+			this.jdk = getDefaultJdk();
+		}
+
+		public String getName() {
+			return name;
+		}
+
+		public Configuration getTestingRuntimeConfiguration() {
+			return jdbcDependencies;
+		}
+
+		public Jdk getTestingRuntimeJdk() {
+			return jdk;
+		}
+	}
+
+	/**
+	 * Provides simplified convention object to the database-specific script for convenient configuration.
+	 */
+	private class MatrixDotGradleMatrixNodeConvention {
+		private final MatrixDotGradleMatrixNodeImpl matrixNode;
+
+		private MatrixDotGradleMatrixNodeConvention(MatrixDotGradleMatrixNodeImpl matrixNode) {
+			this.matrixNode = matrixNode;
+		}
+
+		public void jdbcDependency(Object dependencyNotation, Closure closure) {
+			project.getDependencies().add( matrixNode.jdbcDependencies.getName(), dependencyNotation, closure );
+		}
+
+		public void jdbcDependency(Object dependencyNotation) {
+			project.getDependencies().add( matrixNode.jdbcDependencies.getName(), dependencyNotation );
+		}
+
+		public void jdk(Jdk jdk) {
+			matrixNode.jdk = jdk;
+		}
+	}
+
+	private MatrixNode prepareFromIvyXmlFile(File ivyXmlFile) {
+		return new IvyXmlMatrixNode( ivyXmlFile );
+	}
+
+	private class IvyXmlMatrixNode implements MatrixNode {
+		private final String name;
+		private final Configuration jdbcDependencies;
+		private final Jdk jdk = getDefaultJdk();
+
+		private IvyXmlMatrixNode(File ivyXmlFile) {
+			name = ivyXmlFile.getParentFile().getName();
+			jdbcDependencies = getOrCreateConfiguration( name );
+			jdbcDependencies.addDependency( new IvyXmlDependency( project, ivyXmlFile ) );
+		}
+
+		public String getName() {
+			return name;
+		}
+
+		public Configuration getTestingRuntimeConfiguration() {
+			return jdbcDependencies;
+		}
+
+		public Jdk getTestingRuntimeJdk() {
+			return jdk;
+		}
+	}
+
+	private MatrixNode prepareFromJdbcDir(File jdbcDir) {
+		return new LocalMatrixNode( jdbcDir );
+	}
+
+	private class LocalMatrixNode implements MatrixNode {
+		private final String name;
+		private final Configuration jdbcDependencies;
+		private final Jdk jdk = getDefaultJdk();
+
+		private LocalMatrixNode(File jdbcDir) {
+			name = jdbcDir.getParentFile().getName();
+			jdbcDependencies = getOrCreateConfiguration( name );
+			jdbcDependencies.addDependency(
+					new DefaultSelfResolvingDependency( project.files( (File[]) jdbcDir.listFiles() ) )
 			);
 		}
 
-		matrixNodes.add(
-				new MatrixNode() {
-					public String getName() {
-						return databaseName;
-					}
+		public String getName() {
+			return name;
+		}
 
-					public Configuration getTestingRuntimeConfiguration() {
-						return configuration;
-					}
+		public Configuration getTestingRuntimeConfiguration() {
+			return jdbcDependencies;
+		}
 
-					public Jdk getTestingRuntimeJdk() {
-						return null;
-					}
-				}
-		);
+		public Jdk getTestingRuntimeJdk() {
+			return jdk;
+		}
 	}
 
 	private Configuration prepareJdbcDependencies(File databaseDir) {
@@ -125,4 +273,23 @@
 	public List<MatrixNode> getMatrixNodes() {
 		return matrixNodes;
 	}
+
+	private Configuration prepareConfiguration(String name) {
+		Configuration configuration = getOrCreateConfiguration( name );
+		configuration.setVisible( true );
+		configuration.setDescription( "The [" + name + "] JDBC dependency configuration" );
+		return configuration;
+	}
+
+	private Configuration getOrCreateConfiguration(String configurationName) {
+		Configuration configuration = project.getConfigurations().findByName( configurationName );
+		if ( configuration == null ) {
+			configuration = project.getConfigurations().add( configurationName );
+		}
+		return configuration;
+	}
+
+	private Jdk getDefaultJdk() {
+		return (Jdk) project.getProperties().get( "java5Home" );
+	}
 }

Added: core/branches/gradle2/buildSrc/src/main/java/org/hibernate/gradle/testing/database/IvyXmlDependency.java
===================================================================
--- core/branches/gradle2/buildSrc/src/main/java/org/hibernate/gradle/testing/database/IvyXmlDependency.java	                        (rev 0)
+++ core/branches/gradle2/buildSrc/src/main/java/org/hibernate/gradle/testing/database/IvyXmlDependency.java	2010-06-28 19:43:57 UTC (rev 19845)
@@ -0,0 +1,194 @@
+package org.hibernate.gradle.testing.database;
+
+import java.io.File;
+import java.io.IOException;
+import java.text.ParseException;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.ivy.Ivy;
+import org.apache.ivy.core.cache.DefaultRepositoryCacheManager;
+import org.apache.ivy.core.cache.RepositoryCacheManager;
+import org.apache.ivy.core.module.descriptor.DependencyDescriptor;
+import org.apache.ivy.core.module.descriptor.ModuleDescriptor;
+import org.apache.ivy.core.module.id.ModuleRevisionId;
+import org.apache.ivy.core.report.ResolveReport;
+import org.apache.ivy.core.settings.IvySettings;
+import org.apache.ivy.plugins.resolver.DependencyResolver;
+import org.gradle.api.Project;
+import org.gradle.api.artifacts.repositories.InternalRepository;
+import org.gradle.api.internal.artifacts.IvyService;
+import org.gradle.api.internal.artifacts.configurations.DefaultConfigurationContainer;
+import org.gradle.api.internal.artifacts.configurations.ResolverProvider;
+import org.gradle.api.internal.artifacts.dependencies.DefaultSelfResolvingDependency;
+import org.gradle.api.internal.artifacts.ivyservice.DefaultIvyService;
+import org.gradle.api.internal.artifacts.ivyservice.ErrorHandlingIvyService;
+import org.gradle.api.internal.artifacts.ivyservice.IvyFactory;
+import org.gradle.api.internal.artifacts.ivyservice.SettingsConverter;
+import org.gradle.api.internal.artifacts.ivyservice.ShortcircuitEmptyConfigsIvyService;
+import org.gradle.api.internal.file.AbstractFileCollection;
+import org.gradle.invocation.DefaultGradle;
+
+import org.hibernate.gradle.util.BuildException;
+import org.hibernate.gradle.util.ResolutionException;
+
+/**
+ * TODO : javadoc
+ *
+ * @author Steve Ebersole
+ */
+public class IvyXmlDependency extends DefaultSelfResolvingDependency {
+	private final String name;
+
+	public IvyXmlDependency(Project project, File ivyXmlFile) {
+		super( new IvyXmlDependencyFileCollection( project, ivyXmlFile ) );
+		this.name = ivyXmlFile.getParentFile().getName() + '/' + ivyXmlFile.getName();
+	}
+
+	@Override
+	public String getName() {
+		return name;
+	}
+
+	@Override
+	public IvyXmlDependencyFileCollection getSource() {
+		return (IvyXmlDependencyFileCollection) super.getSource();
+	}
+
+	private static class IvyXmlDependencyFileCollection extends AbstractFileCollection {
+		private final Project project;
+		private final File ivyXmlFile;
+		private Set<File> resolvedDependencyFiles;
+
+		private IvyXmlDependencyFileCollection(Project project, File ivyXmlFile) {
+			this.project = project;
+			this.ivyXmlFile = ivyXmlFile;
+		}
+
+		public File getIvyXmlFile() {
+			return ivyXmlFile;
+		}
+
+		@Override
+		public String getDisplayName() {
+			return ivyXmlFile.getAbsolutePath();
+		}
+
+		public Set<File> getFiles() {
+			if ( resolvedDependencyFiles == null ) {
+				resolvedDependencyFiles = resolveDependencyFiles();
+			}
+			return resolvedDependencyFiles;
+		}
+
+		private Set<File> resolveDependencyFiles() {
+			DefaultIvyService ivyService = unwrap(
+					( (DefaultConfigurationContainer) project.getConfigurations() ).getIvyService()
+			);
+
+			final ModuleDescriptor moduleDescriptor = resolveIvyXml( ivyService );
+
+			DefaultRepositoryCacheManager repositoryCacheManager = null;
+			final ResolverProvider resolverProvider = ivyService.getResolverProvider();
+			for ( DependencyResolver resolver : resolverProvider.getResolvers() ) {
+				RepositoryCacheManager potentialRepositoryCacheManager = resolver.getRepositoryCacheManager();
+				if ( DefaultRepositoryCacheManager.class.isInstance( potentialRepositoryCacheManager ) ) {
+					repositoryCacheManager = (DefaultRepositoryCacheManager) potentialRepositoryCacheManager;
+				}
+			}
+			if ( repositoryCacheManager == null ) {
+				throw buildResolutionException( moduleDescriptor.getModuleRevisionId(), "Unable to locate proper dependency cache manager" );
+			}
+
+			HashSet<File> dependencyFiles = new HashSet<File>();
+			for ( DependencyDescriptor dependencyDescriptor : moduleDescriptor.getDependencies() ) {
+				final ModuleRevisionId info = dependencyDescriptor.getDynamicConstraintDependencyRevisionId();
+
+				dependencyFiles.add( repositoryCacheManager.getIvyFileInCache( info ) );
+			}
+
+			return dependencyFiles;
+		}
+
+		private DefaultIvyService unwrap(IvyService ivyService) {
+			if ( DefaultIvyService.class.isInstance( ivyService ) ) {
+				return (DefaultIvyService) ivyService;
+			}
+
+			if ( ErrorHandlingIvyService.class.isInstance( ivyService ) ) {
+				return unwrap( ( (ErrorHandlingIvyService) ivyService ).getIvyService() );
+			}
+
+			if ( ShortcircuitEmptyConfigsIvyService.class.isInstance( ivyService ) ) {
+				return unwrap( ( (ShortcircuitEmptyConfigsIvyService) ivyService ).getIvyService() );
+			}
+
+			throw new BuildException( "Do not know how to extract needed ivy config from ivy service of type " + ivyService.getClass().getName() );
+		}
+
+		private ModuleDescriptor resolveIvyXml(DefaultIvyService ivyService) {
+			Ivy ivy = locateIvyService( ivyService );
+			ResolveReport resolveReport = performResolve( ivy, ivyXmlFile );
+			return resolveReport.getModuleDescriptor();
+		}
+
+		@SuppressWarnings({ "unchecked" })
+		private ResolveReport performResolve(Ivy ivy, File ivyXmlFile) {
+			try {
+				ResolveReport resolveReport = ivy.resolve( ivyXmlFile );
+				if ( resolveReport.hasError() ) {
+					throw buildResolutionException(
+							resolveReport.getModuleDescriptor().getModuleRevisionId(),
+							resolveReport.getAllProblemMessages()
+					);
+				}
+				return resolveReport;
+			}
+			catch ( ParseException e ) {
+				throw new BuildException( "Malformed ivy dependency file [" + ivyXmlFile.getName() + "]", e );
+			}
+			catch ( IOException e ) {
+				throw new BuildException( "Problem reading ivy dependency file [" + ivyXmlFile.getName() + "]", e );
+			}
+		}
+
+		private Ivy locateIvyService(DefaultIvyService ivyService) {
+			final IvyFactory ivyFactory = ivyService.getIvyFactory();
+			final SettingsConverter settingsConverter = ivyService.getSettingsConverter();
+			final ResolverProvider resolverProvider = ivyService.getResolverProvider();
+
+			// Ugh, can absolutely find no way to access this other than a bunch of recursive reflection calls to
+			// locate the build's org.gradle.api.internal.project.TopLevelBuildServiceRegistry and access its
+			// private org.gradle.api.internal.project.TopLevelBuildServiceRegistry.clientModuleRegistry field.
+			//
+			// Not sure if it is critical to reuse that map instance or not.  seems to work without, but i have no
+			// idea about the ramifications.
+			Map<String, ModuleDescriptor> clientModuleRegistry = new HashMap<String, ModuleDescriptor>();
+
+			// this part is mainly DefaultIvyService#ivyForResolve
+			IvySettings ivySettings = settingsConverter.convertForResolve(
+					resolverProvider.getResolvers(),
+					project.getGradle().getGradleUserHomeDir(),
+					getGradeService( InternalRepository.class ),
+					clientModuleRegistry
+			);
+			return ivyFactory.createIvy( ivySettings );
+		}
+
+		protected <T> T getGradeService(Class<T> type) {
+			return ( (DefaultGradle) project.getGradle() ).getServiceRegistryFactory().get( type );
+		}
+	}
+
+	private static ResolutionException buildResolutionException(ModuleRevisionId descriptor, List<String> messages) {
+		return new ResolutionException( descriptor.toString(), messages );
+	}
+
+	private static ResolutionException buildResolutionException(ModuleRevisionId descriptor, String... messages) {
+		return buildResolutionException( descriptor, Arrays.asList( messages ) );
+	}
+}



More information about the hibernate-commits mailing list