de.juplo.plugins.hibernate.AbstractSchemaMojo Maven / Gradle / Ivy
Show all versions of hibernate-maven-plugin Show documentation
package de.juplo.plugins.hibernate;
import com.pyx4j.log4j.MavenLogAppender;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.NoSuchAlgorithmException;
import java.time.ZonedDateTime;
import java.util.Collections;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.persistence.Embeddable;
import javax.persistence.Entity;
import javax.persistence.MappedSuperclass;
import javax.persistence.spi.PersistenceUnitTransactionType;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.model.Resource;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.project.MavenProject;
import org.hibernate.boot.MetadataBuilder;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.cfgxml.internal.ConfigLoader;
import org.hibernate.boot.cfgxml.spi.LoadedConfig;
import org.hibernate.boot.cfgxml.spi.MappingReference;
import org.hibernate.boot.model.naming.ImplicitNamingStrategy;
import org.hibernate.boot.model.naming.PhysicalNamingStrategy;
import org.hibernate.boot.registry.BootstrapServiceRegistry;
import org.hibernate.boot.registry.BootstrapServiceRegistryBuilder;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
import org.hibernate.boot.registry.classloading.spi.ClassLoadingException;
import org.hibernate.boot.registry.selector.spi.StrategySelector;
import org.hibernate.boot.spi.MetadataImplementor;
import org.hibernate.cfg.AvailableSettings;
import static org.hibernate.cfg.AvailableSettings.DIALECT;
import static org.hibernate.cfg.AvailableSettings.DRIVER;
import static org.hibernate.cfg.AvailableSettings.FORMAT_SQL;
import static org.hibernate.cfg.AvailableSettings.HBM2DDL_DELIMITER;
import static org.hibernate.cfg.AvailableSettings.HBM2DLL_CREATE_NAMESPACES;
import static org.hibernate.cfg.AvailableSettings.IMPLICIT_NAMING_STRATEGY;
import static org.hibernate.cfg.AvailableSettings.JPA_JDBC_DRIVER;
import static org.hibernate.cfg.AvailableSettings.JPA_JDBC_PASSWORD;
import static org.hibernate.cfg.AvailableSettings.JPA_JDBC_URL;
import static org.hibernate.cfg.AvailableSettings.JPA_JDBC_USER;
import static org.hibernate.cfg.AvailableSettings.PASS;
import static org.hibernate.cfg.AvailableSettings.PHYSICAL_NAMING_STRATEGY;
import static org.hibernate.cfg.AvailableSettings.SHOW_SQL;
import static org.hibernate.cfg.AvailableSettings.USER;
import static org.hibernate.cfg.AvailableSettings.URL;
import org.hibernate.engine.config.spi.ConfigurationService;
import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider;
import org.hibernate.internal.util.config.ConfigurationException;
import org.hibernate.jpa.boot.internal.ParsedPersistenceXmlDescriptor;
import org.hibernate.jpa.boot.internal.PersistenceXmlParser;
import org.hibernate.tool.schema.TargetType;
import org.hibernate.tool.schema.internal.ExceptionHandlerCollectingImpl;
import org.hibernate.tool.schema.internal.exec.ScriptTargetOutputToFile;
import org.hibernate.tool.schema.spi.ExecutionOptions;
import org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator;
import org.hibernate.tool.schema.spi.ScriptTargetOutput;
import org.hibernate.tool.schema.spi.TargetDescriptor;
import org.scannotation.AnnotationDB;
/**
* Baseclass with common attributes and methods.
*
* @phase process-classes
* @threadSafe
* @requiresDependencyResolution runtime
*/
public abstract class AbstractSchemaMojo extends AbstractMojo
{
public final static String EXECUTE = "hibernate.schema.execute";
public final static String OUTPUTDIRECTORY = "project.build.outputDirectory";
public final static String SCAN_CLASSES = "hibernate.schema.scan.classes";
public final static String SCAN_DEPENDENCIES = "hibernate.schema.scan.dependencies";
public final static String SCAN_TESTCLASSES = "hibernate.schema.scan.test_classes";
public final static String TEST_OUTPUTDIRECTORY = "project.build.testOutputDirectory";
public final static String SKIPPED = "hibernate.schema.skipped";
public final static String SCRIPT = "hibernate.schema.script";
private final static Pattern SPLIT = Pattern.compile("[^,\\s]+");
private final Set packages = new HashSet();
/**
* The maven project.
*
* Only needed internally.
*
* @parameter property="project"
* @required
* @readonly
*/
private MavenProject project;
/**
* Build-directory.
*
* Only needed internally.
*
* @parameter property="project.build.directory"
* @required
* @readonly
*/
private String buildDirectory;
/** Parameters to configure the genaration of the SQL *********************/
/**
* Excecute the generated SQL.
* If set to false, only the SQL-script is created and the
* database is not touched.
*
* Important:
* This configuration value can only be configured through the
* pom.xml, or by the definition of a system-property, because
* it is not known by Hibernate nor JPA and, hence, not picked up from
* their configuration!
*
* @parameter property="hibernate.schema.execute" default-value="true"
* @since 2.0
*/
private Boolean execute;
/**
* Skip execution
*
* If set to true, the execution is skipped.
*
* A skipped execution is signaled via the maven-property
* ${hibernate.schema.skipped}.
*
* The execution is skipped automatically, if no modified or newly added
* annotated classes are found and the dialect was not changed.
*
* Important:
* This configuration value can only be configured through the
* pom.xml, or by the definition of a system-property, because
* it is not known by Hibernate nor JPA and, hence, not picked up from
* their configuration!
*
* @parameter property="hibernate.schema.skip" default-value="${maven.test.skip}"
* @since 1.0
*/
private boolean skip;
/**
* Force generation/execution
*
* Force the generation and (if configured) the execution of the SQL, even if
* no modified or newly added annotated classes where found and the
* configuration was not changed.
*
* skip takes precedence over force.
*
* Important:
* This configuration value can only be configured through the
* pom.xml, or by the definition of a system-property, because
* it is not known by Hibernate nor JPA and, hence, not picked up from
* their configuration!
*
* @parameter property="hibernate.schema.force" default-value="false"
* @since 1.0
*/
private boolean force;
/**
* Hibernate dialect.
*
* @parameter property="hibernate.dialect"
* @since 1.0
*/
private String dialect;
/**
* Delimiter in output-file.
*
* Important:
* This configuration value can only be configured through the
* pom.xml, or by the definition of a system-property, because
* it is not known by Hibernate nor JPA and, hence, not picked up from
* their configuration!
*
* @parameter property="hibernate.hbm2ddl.delimiter" default-value=";"
* @since 1.0
*/
private String delimiter;
/**
* Show the generated SQL in the command-line output.
*
* @parameter property="hibernate.show_sql"
* @since 1.0
*/
private Boolean show;
/**
* Format output-file.
*
* @parameter property="hibernate.format_sql"
* @since 1.0
*/
private Boolean format;
/**
* Specifies whether to automatically create also the database schema/catalog.
*
* @parameter property="hibernate.hbm2dll.create_namespaces" default-value="false"
* @since 2.0
*/
private Boolean createNamespaces;
/**
* Implicit naming strategy
*
* @parameter property="hibernate.implicit_naming_strategy"
* @since 2.0
*/
private String implicitNamingStrategy;
/**
* Physical naming strategy
*
* @parameter property="hibernate.physical_naming_strategy"
* @since 2.0
*/
private String physicalNamingStrategy;
/**
* Wether the project should be scanned for annotated-classes, or not
*
* This parameter is intended to allow overwriting of the parameter
* exclude-unlisted-classes of a persistence-unit.
* If not specified, it defaults to true
*
* @parameter property="hibernate.schema.scan.classes"
* @since 2.0
*/
private Boolean scanClasses;
/**
* Classes-Directory to scan.
*
* This parameter defaults to the maven build-output-directory for classes.
* Additionally, all dependencies are scanned for annotated classes.
*
* Important:
* This configuration value can only be configured through the
* pom.xml, or by the definition of a system-property, because
* it is not known by Hibernate nor JPA and, hence, not picked up from
* their configuration!
*
* @parameter property="project.build.outputDirectory"
* @since 1.0
*/
private String outputDirectory;
/**
* Dependency-Scopes, that should be scanned for annotated classes.
*
* By default, only dependencies in the scope compile are
* scanned for annotated classes. Multiple scopes can be seperated by
* white space or commas.
*
* If you do not want any dependencies to be scanned for annotated
* classes, set this parameter to none.
*
* The plugin does not scan for annotated classes in transitive
* dependencies. If some of your annotated classes are hidden in a
* transitive dependency, you can simply add that dependency explicitly.
*
* @parameter property="hibernate.schema.scan.dependencies" default-value="compile"
* @since 1.0.3
*/
private String scanDependencies;
/**
* Whether to scan the test-branch of the project for annotated classes, or
* not.
*
* If this parameter is set to true the test-classes of the
* artifact will be scanned for hibernate-annotated classes additionally.
*
* Important:
* This configuration value can only be configured through the
* pom.xml, or by the definition of a system-property, because
* it is not known by Hibernate nor JPA and, hence, not picked up from
* their configuration!
*
* @parameter property="hibernate.schema.scan.test_classes" default-value="false"
* @since 1.0.1
*/
private Boolean scanTestClasses;
/**
* Test-Classes-Directory to scan.
*
* This parameter defaults to the maven build-output-directory for
* test-classes.
*
* This parameter is only used, when scanTestClasses is set
* to true!
*
* Important:
* This configuration value can only be configured through the
* pom.xml, or by the definition of a system-property, because
* it is not known by Hibernate nor JPA and, hence, not picked up from
* their configuration!
*
* @parameter property="project.build.testOutputDirectory"
* @since 1.0.2
*/
private String testOutputDirectory;
/** Conection parameters *************************************************/
/**
* SQL-Driver name.
*
* @parameter property="hibernate.connection.driver_class"
* @since 1.0
*/
private String driver;
/**
* Database URL.
*
* @parameter property="hibernate.connection.url"
* @since 1.0
*/
private String url;
/**
* Database username
*
* @parameter property="hibernate.connection.username"
* @since 1.0
*/
private String username;
/**
* Database password
*
* @parameter property="hibernate.connection.password"
* @since 1.0
*/
private String password;
/** Parameters to locate configuration sources ****************************/
/**
* Path to a file or name of a ressource with hibernate properties.
* If this parameter is specified, the plugin will try to load configuration
* values from a file with the given path or a ressource on the classpath with
* the given name. If both fails, the execution of the plugin will fail.
*
* If this parameter is not set the plugin will load configuration values
* from a ressource named hibernate.properties on the classpath,
* if it is present, but will not fail if there is no such ressource.
*
* During ressource-lookup, the test-classpath takes precedence.
*
* @parameter
* @since 1.0
*/
private String hibernateProperties;
/**
* Path to Hibernate configuration file (.cfg.xml).
* If this parameter is specified, the plugin will try to load configuration
* values from a file with the given path or a ressource on the classpath with
* the given name. If both fails, the execution of the plugin will fail.
*
* If this parameter is not set the plugin will load configuration values
* from a ressource named hibernate.cfg.xml on the classpath,
* if it is present, but will not fail if there is no such ressource.
*
* During ressource-lookup, the test-classpath takes precedence.
*
* Settings in this file will overwrite settings in the properties file.
*
* @parameter
* @since 1.1.0
*/
private String hibernateConfig;
/**
* Name of the persistence-unit.
* If this parameter is specified, the plugin will try to load configuration
* values from a persistence-unit with the specified name. If no such
* persistence-unit can be found, the plugin will throw an exception.
*
* If this parameter is not set and there is only one persistence-unit
* available, that unit will be used automatically. But if this parameter is
* not set and there are multiple persistence-units available on,
* the class-path, the execution of the plugin will fail.
*
* Settings in this file will overwrite settings in the properties or the
* configuration file.
*
* @parameter
* @since 1.1.0
*/
private String persistenceUnit;
/**
* List of Hibernate-Mapping-Files (XML).
* Multiple files can be separated with white-spaces and/or commas.
*
* @parameter property="hibernate.mapping"
* @since 1.0.2
*/
private String mappings;
public final void execute(String filename)
throws
MojoFailureException,
MojoExecutionException
{
if (skip)
{
getLog().info("Execution of hibernate-maven-plugin was skipped!");
project.getProperties().setProperty(SKIPPED, "true");
return;
}
ModificationTracker tracker;
try
{
tracker = new ModificationTracker(buildDirectory, filename, getLog());
}
catch (NoSuchAlgorithmException e)
{
throw new MojoFailureException("Digest-Algorithm MD5 is missing!", e);
}
final SimpleConnectionProvider connectionProvider =
new SimpleConnectionProvider(getLog());
try
{
/** Start extended logging */
MavenLogAppender.startPluginLog(this);
/** Load checksums for old mapping and configuration */
tracker.load();
/** Create the ClassLoader */
MutableClassLoader classLoader = createClassLoader();
/** Create a BootstrapServiceRegistry with the created ClassLoader */
BootstrapServiceRegistry bootstrapServiceRegitry =
new BootstrapServiceRegistryBuilder()
.applyClassLoader(classLoader)
.build();
ClassLoaderService classLoaderService =
bootstrapServiceRegitry.getService(ClassLoaderService.class);
Properties properties = new Properties();
ConfigLoader configLoader = new ConfigLoader(bootstrapServiceRegitry);
/** Loading configuration */
properties.putAll(loadProperties(configLoader));
LoadedConfig config = loadConfig(configLoader);
if (config != null)
properties.putAll(config.getConfigurationValues());
/** Add the remaining class-path-elements */
addDirectDependenciesClassPath(classLoader);
/** Loading and merging configuration from persistence-unit(s) */
ParsedPersistenceXmlDescriptor unit =
loadPersistenceUnit(classLoaderService, properties);
if (unit != null)
properties.putAll(unit.getProperties());
/** Overwriting/Completing configuration */
configure(properties, tracker);
/** Check configuration for modifications */
if(tracker.track(properties))
getLog().debug("Configuration has changed.");
else
getLog().debug("Configuration unchanged.");
/** Check, that the outputfile is writable */
final File output = getOutputFile(filename);
/** Check, if the outputfile is missing or was changed */
checkOutputFile(output, tracker);
/** Configure Hibernate */
final StandardServiceRegistry serviceRegistry =
new StandardServiceRegistryBuilder(bootstrapServiceRegitry)
.applySettings(properties)
.addService(ConnectionProvider.class, connectionProvider)
.build();
final MetadataSources sources = new MetadataSources(serviceRegistry);
/** Add the remaining class-path-elements */
addAllDependenciesToClassPath(classLoader);
/** Apply mappings from hibernate-configuration, if present */
if (config != null)
{
for (MappingReference mapping : config.getMappingReferences())
mapping.apply(sources);
}
Set classes;
if (unit == null)
{
/** No persistent unit: default behaviour */
if (scanClasses == null)
scanClasses = true;
Set urls = new HashSet();
getLog().debug("Compiling the dependencies, that are scanned for annotated classes");
if (scanClasses)
addRoot(urls, outputDirectory);
if (scanTestClasses)
addRoot(urls, testOutputDirectory);
addDependencies(urls);
classes = scanUrls(urls);
}
else
{
/** Follow configuration in persisten unit */
if (scanClasses == null)
scanClasses = !unit.isExcludeUnlistedClasses();
getLog().debug("Compiling the dependencies, that are scanned for annotated classes");
Set urls = new HashSet();
if (scanClasses)
{
getLog().debug("Only dependencies relative to persistent-unit " + unit.getName() + " are scanned!");
/**
* Scan the root of the persiten unit and configured jars for
* annotated classes
*/
getLog().debug(" - adding " + unit.getPersistenceUnitRootUrl());
urls.add(unit.getPersistenceUnitRootUrl());
for (URL url : unit.getJarFileUrls())
{
getLog().debug(" - adding " + url);
urls.add(url);
}
if (scanTestClasses)
addRoot(urls, testOutputDirectory);
}
else
getLog().debug("Scanning of unlisted classes is prohibited in persistent-unit " + unit.getName());
classes = scanUrls(urls);
for (String className : unit.getManagedClassNames())
classes.add(className);
/**
* Add mappings from the default mapping-file
* META-INF/orm.xml, if present
*/
boolean error = false;
InputStream is;
is = classLoader.getResourceAsStream("META-INF/orm.xml");
if (is != null)
{
getLog().info("Adding default JPA-XML-mapping from META-INF/orm.xml");
try
{
tracker.track("META-INF/orm.xml", is);
sources.addResource("META-INF/orm.xml");
}
catch (IOException e)
{
getLog().error("cannot read META-INF/orm.xml: " + e);
error = true;
}
}
else
{
getLog().debug("no META-INF/orm.xml found");
}
/**
* Add mappings from files, that are explicitly configured in the
* persistence unit
*/
getLog().info("Adding mappings from persistence-unit " + unit.getName());
for (String mapping : unit.getMappingFileNames())
{
getLog().info(" - adding " + mapping);
is = classLoader.getResourceAsStream(mapping);
if (is != null)
{
try
{
tracker.track(mapping, is);
sources.addResource(mapping);
}
catch (IOException e)
{
getLog().info("cannot read mapping-file " + mapping + ": " + e);
error = true;
}
}
else
{
getLog().error("cannot find mapping-file " + mapping);
error = true;
}
}
if (error)
throw new MojoFailureException(
"error, while reading mappings configured in persistence-unit \"" +
unit.getName() +
"\""
);
}
/** Add the configured/collected annotated classes */
for (String className : classes)
addAnnotated(className, sources, classLoaderService, tracker);
/** Add explicitly configured classes */
addMappings(sources, tracker);
/** Skip execution, if mapping and configuration is unchanged */
if (!tracker.modified())
{
getLog().info("Mapping and configuration unchanged.");
if (force)
getLog().info("Generation/execution is forced!");
else
{
getLog().info("Skipping schema generation!");
project.getProperties().setProperty(SKIPPED, "true");
return;
}
}
/** Truncate output file */
try
{
new FileOutputStream(output).getChannel().truncate(0).close();
}
catch (IOException e)
{
String error =
"Error while truncating " + output.getAbsolutePath() + ": "
+ e.getMessage();
getLog().warn(error);
throw new MojoExecutionException(error);
}
/** Create a connection, if sufficient configuration infromation is available */
connectionProvider.open(classLoaderService, properties);
MetadataBuilder metadataBuilder = sources.getMetadataBuilder();
StrategySelector strategySelector =
serviceRegistry.getService(StrategySelector.class);
if (properties.containsKey(IMPLICIT_NAMING_STRATEGY))
{
metadataBuilder.applyImplicitNamingStrategy(
strategySelector.resolveStrategy(
ImplicitNamingStrategy.class,
properties.getProperty(IMPLICIT_NAMING_STRATEGY)
)
);
}
if (properties.containsKey(PHYSICAL_NAMING_STRATEGY))
{
metadataBuilder.applyPhysicalNamingStrategy(
strategySelector.resolveStrategy(
PhysicalNamingStrategy.class,
properties.getProperty(PHYSICAL_NAMING_STRATEGY)
)
);
}
/** Prepare the generation of the SQL */
Map settings = new HashMap();
settings.putAll(
serviceRegistry
.getService(ConfigurationService.class)
.getSettings()
);
ExceptionHandlerCollectingImpl handler =
new ExceptionHandlerCollectingImpl();
ExecutionOptions options =
SchemaManagementToolCoordinator
.buildExecutionOptions(settings, handler);
final EnumSet targetTypes = EnumSet.of(TargetType.SCRIPT);
if (execute)
targetTypes.add(TargetType.DATABASE);
TargetDescriptor target = new TargetDescriptor()
{
@Override
public EnumSet getTargetTypes()
{
return targetTypes;
}
@Override
public ScriptTargetOutput getScriptTargetOutput()
{
String charset =
(String)
serviceRegistry
.getService(ConfigurationService.class)
.getSettings()
.get(AvailableSettings.HBM2DDL_CHARSET_NAME);
return new ScriptTargetOutputToFile(output, charset);
}
};
/**
* Change class-loader of current thread.
* This is necessary, because still not all parts of Hibernate 5 use
* the newly introduced ClassLoaderService and will fail otherwise!
*/
Thread thread = Thread.currentThread();
ClassLoader contextClassLoader = thread.getContextClassLoader();
try
{
thread.setContextClassLoader(classLoader);
build((MetadataImplementor)metadataBuilder.build(), options, target);
if (handler.getExceptions().size() > 0)
{
StringBuilder builder = new StringBuilder();
builder.append("Hibernate failed:");
for (Exception e : handler.getExceptions())
{
builder.append("\n * ");
builder.append(e.getMessage());
AbstractSchemaMojo.printStrackTrace(builder, e);
builder.append("\n");
}
String error = builder.toString();
getLog().error(error);
throw new MojoFailureException(error);
}
}
finally
{
thread.setContextClassLoader(contextClassLoader);
/** Track, the content of the generated script */
checkOutputFile(output, tracker);
}
}
catch (MojoExecutionException e)
{
tracker.failed();
throw e;
}
catch (MojoFailureException e)
{
tracker.failed();
throw e;
}
catch (RuntimeException e)
{
tracker.failed();
throw e;
}
finally
{
/** Remember mappings and configuration */
tracker.save();
/** Close the connection - if one was opened */
connectionProvider.close();
/** Stop Log-Capturing */
MavenLogAppender.endPluginLog(this);
}
}
abstract void build(
MetadataImplementor metadata,
ExecutionOptions options,
TargetDescriptor target
)
throws
MojoFailureException,
MojoExecutionException;
private MutableClassLoader createClassLoader() throws MojoExecutionException
{
try
{
getLog().debug("Creating ClassLoader for project-dependencies...");
LinkedHashSet urls = new LinkedHashSet();
File file;
file = new File(testOutputDirectory);
if (!file.exists())
{
getLog().info("Creating test-output-directory: " + testOutputDirectory);
file.mkdirs();
}
urls.add(file.toURI().toURL());
file = new File(outputDirectory);
if (!file.exists())
{
getLog().info("Creating output-directory: " + outputDirectory);
file.mkdirs();
}
urls.add(file.toURI().toURL());
return new MutableClassLoader(urls, getLog());
}
catch (Exception e)
{
getLog().error("Error while creating ClassLoader!", e);
throw new MojoExecutionException(e.getMessage());
}
}
private void addDirectDependenciesClassPath(MutableClassLoader classLoader)
throws
MojoExecutionException
{
try
{
getLog().debug("Adding all direct project-dependencies to the ClassLoader...");
LinkedHashSet urls = new LinkedHashSet();
addDependencies(urls);
if (scanTestClasses)
addRoot(urls, testOutputDirectory);
classLoader.add(urls);
}
catch (Exception e)
{
getLog().error("Error while creating ClassLoader!", e);
throw new MojoExecutionException(e.getMessage());
}
}
private void addAllDependenciesToClassPath(MutableClassLoader classLoader)
throws
MojoExecutionException
{
try
{
getLog().debug("Adding all project-dependencies to the ClassLoader...");
List classpathFiles = project.getCompileClasspathElements();
classpathFiles.addAll(project.getTestClasspathElements());
LinkedHashSet urls = new LinkedHashSet();
for (String pathElement : classpathFiles)
{
getLog().debug(" - adding " + pathElement);
urls.add(new File(pathElement).toURI().toURL());
}
classLoader.add(urls);
}
catch (Exception e)
{
getLog().error("Error while creating ClassLoader!", e);
throw new MojoExecutionException(e.getMessage());
}
}
private Map loadProperties(ConfigLoader configLoader)
throws
MojoExecutionException
{
/** Try to read configuration from properties-file */
if (hibernateProperties == null)
{
try
{
return configLoader.loadProperties("hibernate.properties");
}
catch (ConfigurationException e)
{
getLog().debug(e.getMessage());
return Collections.EMPTY_MAP;
}
}
else
{
try
{
File file = new File(hibernateProperties);
if (file.exists())
{
getLog().info("Reading settings from file " + hibernateProperties + "...");
return configLoader.loadProperties(file);
}
else
return configLoader.loadProperties(hibernateProperties);
}
catch (ConfigurationException e)
{
getLog().error("Error while reading properties!", e);
throw new MojoExecutionException(e.getMessage());
}
}
}
private LoadedConfig loadConfig(ConfigLoader configLoader)
throws MojoExecutionException
{
/** Try to read configuration from configuration-file */
if (hibernateConfig == null)
{
try
{
return configLoader.loadConfigXmlResource("hibernate.cfg.xml");
}
catch (ConfigurationException e)
{
getLog().debug(e.getMessage());
return null;
}
}
else
{
try
{
File file = new File(hibernateConfig);
if (file.exists())
{
getLog().info("Reading configuration from file " + hibernateConfig + "...");
return configLoader.loadConfigXmlFile(file);
}
else
{
return configLoader.loadConfigXmlResource(hibernateConfig);
}
}
catch (ConfigurationException e)
{
getLog().error("Error while reading configuration!", e);
throw new MojoExecutionException(e.getMessage());
}
}
}
private void configure(Properties properties, ModificationTracker tracker)
throws MojoFailureException
{
/**
* Special treatment for the configuration-value "execute": if it is
* switched to "true", the genearation fo the schema should be forced!
*/
if (tracker.check(EXECUTE, execute.toString()) && execute)
{
getLog().info(
"hibernate.schema.execute was switched on: " +
"forcing generation/execution of SQL"
);
tracker.touch();
}
configure(properties, execute, EXECUTE);
/**
* Configure the generation of the SQL.
* Overwrite values from properties-file if the configuration parameter is
* known to Hibernate.
*/
configure(properties, dialect, DIALECT);
configure(properties, delimiter, HBM2DDL_DELIMITER);
configure(properties, format, FORMAT_SQL);
configure(properties, createNamespaces, HBM2DLL_CREATE_NAMESPACES);
configure(properties, implicitNamingStrategy, IMPLICIT_NAMING_STRATEGY);
configure(properties, physicalNamingStrategy, PHYSICAL_NAMING_STRATEGY);
configure(properties, outputDirectory, OUTPUTDIRECTORY);
configure(properties, scanDependencies, SCAN_DEPENDENCIES);
configure(properties, scanTestClasses, SCAN_TESTCLASSES);
configure(properties, testOutputDirectory, TEST_OUTPUTDIRECTORY);
/**
* Special treatment for the configuration-value "show": a change of its
* configured value should not lead to a regeneration of the database
* schama!
*/
if (show == null)
show = Boolean.valueOf(properties.getProperty(SHOW_SQL));
else
properties.setProperty(SHOW_SQL, show.toString());
/**
* Configure the connection parameters.
* Overwrite values from properties-file.
*/
configure(properties, driver, DRIVER, JPA_JDBC_DRIVER);
configure(properties, url, URL, JPA_JDBC_URL);
configure(properties, username, USER, JPA_JDBC_USER);
configure(properties, password, PASS, JPA_JDBC_PASSWORD);
if (properties.isEmpty())
{
getLog().error("No properties set!");
throw new MojoFailureException("Hibernate configuration is missing!");
}
getLog().info("Gathered configuration:");
for (Entry