/* * 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.testing.database; import java.io.File; import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Set; import org.gradle.api.Plugin; import org.gradle.api.Project; import org.gradle.api.logging.Logger; import org.gradle.api.logging.Logging; /** * Plugin used to apply notion of database profiles, which are consumed by the matrix testing plugin. * * @author Steve Ebersole * @author Strong Liu */ public class DatabaseProfilePlugin implements Plugin<Project> { /** * The directory containing standard database profiles. */ public static final String STANDARD_DATABASES_DIRECTORY = "databases"; /** * Names a system setting key that can be set to point to a directory containing additional, custom * database profiles. */ public static final String CUSTOM_DATABASES_DIRECTORY_KEY = "hibernate-matrix-databases"; public static final String HIBERNATE_MATRIX_IGNORE = "hibernate-matrix-ignore"; private static final String MATRIX_BUILD_FILE = "matrix.gradle"; private static final String JDBC_DIR = "jdbc"; private static final Logger log = Logging.getLogger( DatabaseProfilePlugin.class ); private Project project; private List<DatabaseProfile> profiles; public void apply(Project project) { this.project = project; final LinkedHashMap<String, DatabaseProfile> profileMap = new LinkedHashMap<String, DatabaseProfile>(); processStandardProfiles( profileMap ); processCustomProfiles( profileMap ); this.profiles = new ArrayList<DatabaseProfile>(); DatabaseAllocationCleanUp listener = new DatabaseAllocationCleanUp(); project.getGradle().addBuildListener( listener ); for ( DatabaseProfile profile : profileMap.values() ) { this.profiles.add( profile ); listener.addDatabaseAllocation( profile.getDatabaseAllocation() ); } } private void processStandardProfiles(Map<String, DatabaseProfile> profileMap) { final File standardDatabasesDirectory = project.file( STANDARD_DATABASES_DIRECTORY ); if ( standardDatabasesDirectory == null || ! standardDatabasesDirectory.exists() ) { log.debug( "Standard databases directory [{}] did not exist", STANDARD_DATABASES_DIRECTORY ); return; } if ( ! standardDatabasesDirectory.isDirectory() ) { log.warn( "Located standard databases directory [{}] was not a directory", STANDARD_DATABASES_DIRECTORY ); return; } processProfiles( standardDatabasesDirectory, profileMap ); } private void processProfiles(File directory, Map<String, DatabaseProfile> profileMap) { // the directory itself is a "database directory" if it contains either: // 1) a file named 'matrix.gradle' // 2) a directory named 'jdbc' DatabaseProfile databaseProfile = null; final File matrixDotGradleFile = new File( directory, MATRIX_BUILD_FILE ); if ( matrixDotGradleFile.exists() && matrixDotGradleFile.isFile() ) { log.debug( "Found matrix.gradle file : " + matrixDotGradleFile ); databaseProfile = new MatrixDotGradleProfile( matrixDotGradleFile, project ); } final File jdbcDirectory = new File( directory, JDBC_DIR ); if ( jdbcDirectory.exists() && jdbcDirectory.isDirectory() ) { databaseProfile = new JdbcDirectoryProfile( jdbcDirectory, project ); } if ( databaseProfile == null ) { // we determined this directory is not a database directory, check its sub-directories for ( File subDirectory : directory.listFiles() ) { if ( subDirectory.isDirectory() ) { processProfiles( subDirectory, profileMap ); } } return; // EARLY EXIT!!! } final String profileName = databaseProfile.getName(); if ( ignored().contains( profileName ) ) { log.debug( "Skipping ignored database profile [{}]", profileName ); return; } DatabaseProfile previousEntry = profileMap.put( profileName, databaseProfile ); if ( previousEntry != null ) { log.lifecycle( "Found duplicate profile definitions [name={}], [{}] taking precedence over [{}]", profileName, databaseProfile.getDirectory().getAbsolutePath(), previousEntry.getDirectory().getAbsolutePath() ); } } private Set<String> ignored; private Set<String> ignored() { if ( ignored == null ) { final String values = System.getProperty( HIBERNATE_MATRIX_IGNORE ); if ( values == null || values.length() == 0 ) { ignored = Collections.emptySet(); } else { ignored = new HashSet<String>(); Collections.addAll( ignored, values.split( "," ) ); } } return ignored; } private void processCustomProfiles(Map<String, DatabaseProfile> profileMap) { final String customDatabaseDirectoryPath = System.getProperty( CUSTOM_DATABASES_DIRECTORY_KEY ); if ( customDatabaseDirectoryPath != null && customDatabaseDirectoryPath.length() > 0 ) { final File customDatabaseDirectory = new File( customDatabaseDirectoryPath ); if ( customDatabaseDirectory.exists() && customDatabaseDirectory.isDirectory() ) { processProfiles( customDatabaseDirectory, profileMap ); } } } public Iterable<DatabaseProfile> getDatabaseProfiles() { return profiles; } }