X-Git-Url: https://juplo.de/gitweb/?p=hibernate4-maven-plugin;a=blobdiff_plain;f=src%2Fmain%2Fjava%2Fde%2Fjuplo%2Fplugins%2Fhibernate4%2FHbm2DdlMojo.java;h=fdcad88be8ca1b18060d2f6e2afc4154981736de;hp=fa4ce6a0569b59ced91236db051937e3646e3ff3;hb=9156c5f6414b676d34eb0c934e70604ba822d09a;hpb=74c0dd783b84c90e116f3e7f1c8d6109845ba71f diff --git a/src/main/java/de/juplo/plugins/hibernate4/Hbm2DdlMojo.java b/src/main/java/de/juplo/plugins/hibernate4/Hbm2DdlMojo.java index fa4ce6a0..fdcad88b 100644 --- a/src/main/java/de/juplo/plugins/hibernate4/Hbm2DdlMojo.java +++ b/src/main/java/de/juplo/plugins/hibernate4/Hbm2DdlMojo.java @@ -30,16 +30,15 @@ import java.net.URL; import java.net.URLClassLoader; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; -import java.sql.Connection; import java.sql.Driver; -import java.sql.DriverManager; import java.sql.DriverPropertyInfo; import java.sql.SQLException; import java.sql.SQLFeatureNotSupportedException; +import java.util.Collections; import java.util.Comparator; -import java.util.Enumeration; import java.util.HashMap; import java.util.HashSet; +import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Map.Entry; @@ -52,14 +51,24 @@ 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.registry.StandardServiceRegistryBuilder; +import org.hibernate.boot.registry.classloading.spi.ClassLoaderService; +import org.hibernate.boot.registry.classloading.spi.ClassLoadingException; +import org.hibernate.boot.registry.internal.StandardServiceRegistryImpl; +import org.hibernate.cfg.Environment; import org.hibernate.cfg.NamingStrategy; import org.hibernate.envers.configuration.spi.AuditConfiguration; +import org.hibernate.internal.util.config.ConfigurationHelper; +import org.hibernate.jpa.boot.internal.ParsedPersistenceXmlDescriptor; +import org.hibernate.jpa.boot.internal.PersistenceXmlParser; +import org.hibernate.jpa.boot.spi.ProviderChecker; import org.hibernate.tool.hbm2ddl.SchemaExport; import org.hibernate.tool.hbm2ddl.SchemaExport.Type; import org.hibernate.tool.hbm2ddl.Target; @@ -143,6 +152,9 @@ public class Hbm2DdlMojo extends AbstractMojo * 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. @@ -251,6 +263,15 @@ public class Hbm2DdlMojo extends AbstractMojo */ private String hibernateProperties; + /** + * Name of the persistence-unit. + * If there is only one persistence-unit available, that unit will be used + * automatically. + * + * @since 1.1.0 + */ + private String persistenceUnit; + /** * List of Hibernate-Mapping-Files (XML). * Multiple files can be separated with white-spaces and/or commas. @@ -320,7 +341,7 @@ public class Hbm2DdlMojo extends AbstractMojo /** * Generate envers schema for auditing tables. * - * @parameter property="hibernate.export.envers" default-value="false" + * @parameter property="hibernate.export.envers" default-value="true" * @since 1.0.3 */ private boolean envers; @@ -535,6 +556,15 @@ public class Hbm2DdlMojo extends AbstractMojo throw new MojoExecutionException(e.getMessage()); } + ParsedPersistenceXmlDescriptor persistenceUnitDescriptor = + getPersistenceUnitDescriptor( + persistenceUnit, + properties, + new MavenProjectClassLoaderService(classLoader) + ); + if (persistenceUnitDescriptor != null) + properties = persistenceUnitDescriptor.getProperties(); + /** Overwrite values from properties-file or set, if given */ if (driverClassName != null) { @@ -673,6 +703,13 @@ public class Hbm2DdlMojo extends AbstractMojo throw new MojoFailureException("Hibernate configuration is missing!"); } + getLog().info("Gathered hibernate-configuration (turn on debugging for details):"); + for (Entry entry : properties.entrySet()) + getLog().info(" " + entry.getKey() + " = " + entry.getValue()); + + if (hibernateDialect == null) + throw new MojoFailureException("hibernate-dialect must be set!"); + final ValidationConfiguration config = new ValidationConfiguration(hibernateDialect); config.setProperties(properties); @@ -695,7 +732,6 @@ public class Hbm2DdlMojo extends AbstractMojo } ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader(); - Connection connection = null; MavenLogAppender.startPluginLog(this); try { @@ -824,61 +860,11 @@ public class Hbm2DdlMojo extends AbstractMojo return; } - getLog().info("Gathered hibernate-configuration (turn on debugging for details):"); - for (Entry entry : properties.entrySet()) - getLog().info(" " + entry.getKey() + " = " + entry.getValue()); - - try - { - /** - * The connection must be established outside of hibernate, because - * hibernate does not use the context-classloader of the current - * thread and, hence, would not be able to resolve the driver-class! - */ - getLog().debug("Target: " + target + ", Type: " + type); - switch (target) - { - case EXPORT: - case BOTH: - switch (type) - { - case CREATE: - case DROP: - case BOTH: - Class driverClass = classLoader.loadClass(properties.getProperty(DRIVER_CLASS)); - getLog().debug("Registering JDBC-driver " + driverClass.getName()); - DriverManager.registerDriver(new DriverProxy((Driver)driverClass.newInstance())); - getLog().debug( - "Opening JDBC-connection to " - + properties.getProperty(URL) - + " as " - + properties.getProperty(USERNAME) - + " with password " - + properties.getProperty(PASSWORD) - ); - connection = DriverManager.getConnection( - properties.getProperty(URL), - properties.getProperty(USERNAME), - properties.getProperty(PASSWORD) - ); - } - } - } - catch (ClassNotFoundException e) - { - getLog().error("Dependency for driver-class " + properties.getProperty(DRIVER_CLASS) + " is missing!"); - throw new MojoExecutionException(e.getMessage()); - } - catch (Exception e) - { - getLog().error("Cannot establish connection to database!"); - Enumeration drivers = DriverManager.getDrivers(); - if (!drivers.hasMoreElements()) - getLog().error("No drivers registered!"); - while (drivers.hasMoreElements()) - getLog().debug("Driver: " + drivers.nextElement()); - throw new MojoExecutionException(e.getMessage()); - } + Environment.verifyProperties( properties ); + ConfigurationHelper.resolvePlaceHolders( properties ); + StandardServiceRegistryImpl registry = + (StandardServiceRegistryImpl) + new StandardServiceRegistryBuilder().applySettings(properties).build(); config.buildMappings(); @@ -888,7 +874,7 @@ public class Hbm2DdlMojo extends AbstractMojo AuditConfiguration.getFor(config); } - SchemaExport export = new SchemaExport(config, connection); + SchemaExport export = new SchemaExport(registry, config); export.setDelimiter(delimiter); export.setFormat(format); @@ -929,17 +915,6 @@ public class Hbm2DdlMojo extends AbstractMojo /** Restore the old class-loader (TODO: is this really necessary?) */ Thread.currentThread().setContextClassLoader(contextClassLoader); - - /** Close the connection */ - try - { - if (connection != null) - connection.close(); - } - catch (SQLException e) - { - getLog().error("Error while closing connection: " + e.getMessage()); - } } /** Write md5-sums for annotated classes to file */ @@ -957,6 +932,123 @@ public class Hbm2DdlMojo extends AbstractMojo } } + private ParsedPersistenceXmlDescriptor getPersistenceUnitDescriptor( + String name, + Properties properties, + ClassLoaderService loader + ) + throws + MojoFailureException + { + PersistenceXmlParser parser = + new PersistenceXmlParser( + loader, + PersistenceUnitTransactionType.RESOURCE_LOCAL + ); + + List units = parser.doResolve(properties); + + if (name == null) + { + switch (units.size()) + { + case 0: + getLog().info("Found no META-INF/persistence.xml."); + return null; + case 1: + getLog().info("Using persistence-unit " + units.get(0).getName()); + return units.get(0); + default: + getLog().warn("No name provided and multiple persistence units found:"); + for (ParsedPersistenceXmlDescriptor unit : units) + getLog().warn(" - " + unit.getName()); + return null; + } + + } + + for (ParsedPersistenceXmlDescriptor unit : units) + { + getLog().debug("Found persistence-unit " + unit.getName()); + if (!unit.getName().equals(name)) + continue; + + // See if we (Hibernate) are the persistence provider + if (!ProviderChecker.isProvider(unit, properties)) + { + getLog().debug("Wrong provider: " + unit.getProviderClassName()); + continue; + } + + getLog().info("Using persistence-unit " + unit.getName()); + return unit; + } + + throw new MojoFailureException("Could not find persistence-unit " + name); + } + + + static final class MavenProjectClassLoaderService implements ClassLoaderService + { + final private ClassLoader loader; + + + public MavenProjectClassLoaderService(ClassLoader loader) + { + this.loader = loader; + } + + + @Override + public Class classForName(String name) + { + try + { + return (Class)loader.loadClass(name); + } + catch (ClassNotFoundException e) + { + throw new ClassLoadingException( "Unable to load class [" + name + "]", e ); + } + } + + @Override + public URL locateResource(String name) + { + return loader.getResource(name); + } + + @Override + public InputStream locateResourceStream(String name) + { + return loader.getResourceAsStream(name); + } + + @Override + public List locateResources(String name) + { + try + { + return Collections.list(loader.getResources(name)); + } + catch (IOException e) + { + return Collections.EMPTY_LIST; + } + } + + @Override + public LinkedHashSet loadJavaServices(Class serviceContract) + { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public void stop() { } + + } + + /** * Needed, because DriverManager won't pick up drivers, that were not * loaded by the system-classloader!