From: Kai Moritz Date: Fri, 16 Oct 2015 10:16:30 +0000 (+0200) Subject: Refined reimplementation of the plugin for Hibernate 5.x X-Git-Tag: hibernate-maven-plugin-2.0.0~17 X-Git-Url: https://juplo.de/gitweb/?p=hibernate4-maven-plugin;a=commitdiff_plain;h=4940080670944a15916c68fb294e18a6bfef12d5 Refined reimplementation of the plugin for Hibernate 5.x Renamed the plugin from hibernate4-maven-plugin to hibernate-maven-plugin, because the goal is, to support all recent older versions with the new plugin. --- diff --git a/pom.xml b/pom.xml index a0a92d90..dda23106 100644 --- a/pom.xml +++ b/pom.xml @@ -10,12 +10,12 @@ de.juplo - hibernate4-maven-plugin - Hibernate 4 Maven Plugin - Plugin for generating a database-schema from Hibernate-4-Mapping-Annotations + hibernate-maven-plugin + Hibernate Maven Plugin + Plugin for generating a database-schema from Hibernate-Mapping-Annotations 2.0-SNAPSHOT maven-plugin - http://juplo.de/hibernate4-maven-plugin + http://juplo.de/hibernate-maven-plugin 2.0.6 @@ -31,9 +31,9 @@ - scm:git:http://juplo.de/git/hibernate4-maven-plugin - scm:git:ssh://juplo.de:/var/lib/git/juplo/hibernate4-maven-plugin - http://juplo.de/gitweb/?p=hibernate4-maven-plugin;a=summary + scm:git:http://juplo.de/git/hibernate-maven-plugin + scm:git:ssh://juplo.de:/var/lib/git/juplo/hibernate-maven-plugin + http://juplo.de/gitweb/?p=hibernate-maven-plugin;a=summary @@ -108,7 +108,7 @@ www.juplo.de - scp://juplo.de/var/www/juplo/hibernate4-maven-plugin-${project.version} + scp://juplo.de/var/www/juplo/hibernate-maven-plugin-${project.version} @@ -127,8 +127,8 @@ UTF-8 - 4.3.9.Final - 5.1.3.Final + 5.0.2.Final + 5.2.2.Final 3.0.0 3.3.3 1.0.1 @@ -246,6 +246,9 @@ jar + + -Xdoclint:none + diff --git a/src/it/dependency test/h4mp/pom.xml b/src/it/dependency test/h4mp/pom.xml index 4e179d25..f23648c3 100644 --- a/src/it/dependency test/h4mp/pom.xml +++ b/src/it/dependency test/h4mp/pom.xml @@ -61,23 +61,23 @@ de.juplo - hibernate4-maven-plugin + hibernate-maven-plugin @project.version@ - export + create - NONE + false true true ; true - CREATE - org.hibernate.dialect.PostgreSQL9Dialect + false + org.hibernate.dialect.PostgreSQL9Dialect diff --git a/src/it/h4mp-mod/pom.xml b/src/it/h4mp-mod/pom.xml index 1e05bf6c..c353210f 100644 --- a/src/it/h4mp-mod/pom.xml +++ b/src/it/h4mp-mod/pom.xml @@ -56,23 +56,23 @@ de.juplo - hibernate4-maven-plugin + hibernate-maven-plugin ${version} - export + create - NONE + false true true ; true CREATE - org.hibernate.dialect.PostgreSQL9Dialect + org.hibernate.dialect.PostgreSQL9Dialect diff --git a/src/it/h4mp-mod/schema.sql b/src/it/h4mp-mod/schema.sql index 1fc1d887..9376dd73 100644 --- a/src/it/h4mp-mod/schema.sql +++ b/src/it/h4mp-mod/schema.sql @@ -1,4 +1,6 @@ + create sequence hibernate_sequence start 1 increment 1; + create table MainEntity ( id int8 not null, str varchar(255), @@ -21,8 +23,6 @@ ); alter table MainEntity_AUD - add constraint FK_kpx35pyi0ssiutbfxbf8klu06 + add constraint FKdyho0e2yvr52e1nf5rt18k2ec foreign key (REV) references REVINFO; - - create sequence hibernate_sequence; diff --git a/src/it/hib-test/h2.sql b/src/it/hib-test/h2.sql index 50da4e51..f4fff24a 100644 --- a/src/it/hib-test/h2.sql +++ b/src/it/hib-test/h2.sql @@ -1,6 +1,4 @@ - drop table test_simple if exists; - create table test_simple ( uuid varchar(36) not null, content clob, diff --git a/src/it/hib-test/oracle.sql b/src/it/hib-test/oracle.sql index 37ad1074..15df9419 100644 --- a/src/it/hib-test/oracle.sql +++ b/src/it/hib-test/oracle.sql @@ -1,6 +1,4 @@ - drop table test_simple cascade constraints; - create table test_simple ( uuid varchar2(36 char) not null, content clob, diff --git a/src/it/hib-test/pom.xml b/src/it/hib-test/pom.xml index fe46e321..ba6f6b3f 100644 --- a/src/it/hib-test/pom.xml +++ b/src/it/hib-test/pom.xml @@ -42,42 +42,40 @@ de.juplo - hibernate4-maven-plugin + hibernate-maven-plugin @project.version@ - - none - - both + + false create-h2-ddl - export + create - org.hibernate.dialect.H2Dialect + org.hibernate.dialect.H2Dialect h2.sql create-postgres-ddl - export + create - org.hibernate.dialect.PostgreSQL82Dialect + org.hibernate.dialect.PostgreSQL82Dialect postgres.sql create-oracle-ddl - export + create - org.hibernate.dialect.Oracle10gDialect + org.hibernate.dialect.Oracle10gDialect oracle.sql diff --git a/src/it/hib-test/postgres.sql b/src/it/hib-test/postgres.sql index 43c3d581..99bdf22f 100644 --- a/src/it/hib-test/postgres.sql +++ b/src/it/hib-test/postgres.sql @@ -1,6 +1,4 @@ - drop table if exists test_simple cascade; - create table test_simple ( uuid varchar(36) not null, content text, diff --git a/src/it/hibernate4-maven-plugin-envers-sample/README.md b/src/it/hibernate4-maven-plugin-envers-sample/README.md index cc048a43..792ecc6d 100644 --- a/src/it/hibernate4-maven-plugin-envers-sample/README.md +++ b/src/it/hibernate4-maven-plugin-envers-sample/README.md @@ -30,7 +30,7 @@ Usage __Rebuild the SQL-script using the Hibernate4-maven-plugin to create the database__ - mvn -PcreateHsqlDbScript clean compile hibernate4:export + mvn -PcreateHsqlDbScript clean compile hibernate:export __Build and run the integration tests__ diff --git a/src/it/hibernate4-maven-plugin-envers-sample/pom.xml b/src/it/hibernate4-maven-plugin-envers-sample/pom.xml index 1897c09f..5520ac2c 100644 --- a/src/it/hibernate4-maven-plugin-envers-sample/pom.xml +++ b/src/it/hibernate4-maven-plugin-envers-sample/pom.xml @@ -16,7 +16,7 @@ Sample project to test the maven plugin 1.0-SNAPSHOT jar - http://juplo.de/hibernate4-maven-plugin + http://juplo.de/hibernate-maven-plugin @project.version@ @@ -176,36 +176,36 @@ de.juplo - hibernate4-maven-plugin + hibernate-maven-plugin ${de.juplo-hibernate-plugin-version} create-create-script - export + create ${project.build.directory}/test-classes/sql/create-tables-hsqldb.sql - CREATE + false create-drop-script - export + create ${project.build.directory}/test-classes/sql/drop-tables-hsqldb.sql - DROP + true - SCRIPT - org.hsqldb.jdbc.JDBCDriver - org.hibernate.dialect.HSQLDialect + false + org.hsqldb.jdbc.JDBCDriver + org.hibernate.dialect.HSQLDialect true diff --git a/src/it/ignored-dependency/main/pom.xml b/src/it/ignored-dependency/main/pom.xml index d198fc9b..1dab9a54 100644 --- a/src/it/ignored-dependency/main/pom.xml +++ b/src/it/ignored-dependency/main/pom.xml @@ -30,20 +30,20 @@ de.juplo - hibernate4-maven-plugin + hibernate-maven-plugin @project.version@ - export + create - NONE + false true - CREATE - org.hibernate.dialect.PostgreSQL9Dialect + false + org.hibernate.dialect.PostgreSQL9Dialect none diff --git a/src/it/ignored-dependency/schema.sql b/src/it/ignored-dependency/schema.sql index 510de4f2..d2a1838c 100644 --- a/src/it/ignored-dependency/schema.sql +++ b/src/it/ignored-dependency/schema.sql @@ -1,7 +1,7 @@ + create sequence hibernate_sequence start 1 increment 1; + create table MainEntity ( id int8 not null, primary key (id) ); - - create sequence hibernate_sequence; diff --git a/src/it/properties/h2.sql b/src/it/properties/h2.sql index 9569fa60..10d07285 100644 --- a/src/it/properties/h2.sql +++ b/src/it/properties/h2.sql @@ -1,6 +1,4 @@ - drop table test_simple if exists; - create table test_simple ( uuid varchar(36) not null, content clob, diff --git a/src/it/properties/pom.xml b/src/it/properties/pom.xml index f3a6fc73..7a9922e4 100644 --- a/src/it/properties/pom.xml +++ b/src/it/properties/pom.xml @@ -32,18 +32,16 @@ de.juplo - hibernate4-maven-plugin + hibernate-maven-plugin @project.version@ - - none - - both + + false - export + create diff --git a/src/it/schemaexport-example/schema.sql b/src/it/schemaexport-example/schema.sql index bd7142cd..5c57479e 100644 --- a/src/it/schemaexport-example/schema.sql +++ b/src/it/schemaexport-example/schema.sql @@ -1,26 +1,21 @@ - alter table Employee - drop constraint FK_12v0w2dqasbw95xtn8qc2uj83; - - drop table ABTEILUNG if exists; - - drop table Employee if exists; + create sequence hibernate_sequence start with 1 increment by 1; create table ABTEILUNG ( - OID bigint generated by default as identity (start with 1), + OID bigint not null, gender varchar(255), name varchar(255) not null, primary key (OID) ); create table Employee ( - OID bigint generated by default as identity (start with 1), - name varchar(81) not null, + OID bigint not null, + name varchar(255) not null, FK_department bigint, primary key (OID) ); alter table Employee - add constraint FK_12v0w2dqasbw95xtn8qc2uj83 + add constraint FKps0mm7o60mrhle838yeh1u1rh foreign key (FK_department) references ABTEILUNG; diff --git a/src/it/schemaexport-example/schemaexport-example-persistence-impl/pom.xml b/src/it/schemaexport-example/schemaexport-example-persistence-impl/pom.xml index e7c74191..1215a10c 100644 --- a/src/it/schemaexport-example/schemaexport-example-persistence-impl/pom.xml +++ b/src/it/schemaexport-example/schemaexport-example-persistence-impl/pom.xml @@ -53,25 +53,24 @@ de.juplo - hibernate4-maven-plugin + hibernate-maven-plugin @project.version@ - SCRIPT - org.hsqldb.jdbcDriver - org.hibernate.dialect.HSQLDialect + org.hsqldb.jdbcDriver + org.hibernate.dialect.HSQLDialect - export + create - \ No newline at end of file + diff --git a/src/it/tutorials/annotations/pom.xml b/src/it/tutorials/annotations/pom.xml index fc816f65..47c59916 100644 --- a/src/it/tutorials/annotations/pom.xml +++ b/src/it/tutorials/annotations/pom.xml @@ -48,13 +48,13 @@ de.juplo - hibernate4-maven-plugin + hibernate-maven-plugin ${h4mp.version} process-test-classes - export + create diff --git a/src/it/tutorials/basic/pom.xml b/src/it/tutorials/basic/pom.xml index 5a064d44..69731291 100644 --- a/src/it/tutorials/basic/pom.xml +++ b/src/it/tutorials/basic/pom.xml @@ -47,13 +47,13 @@ de.juplo - hibernate4-maven-plugin + hibernate-maven-plugin ${h4mp.version} process-test-classes - export + create diff --git a/src/it/tutorials/entitymanager/pom.xml b/src/it/tutorials/entitymanager/pom.xml index 5ec5b691..3531d41b 100644 --- a/src/it/tutorials/entitymanager/pom.xml +++ b/src/it/tutorials/entitymanager/pom.xml @@ -55,19 +55,19 @@ de.juplo - hibernate4-maven-plugin + hibernate-maven-plugin ${h4mp.version} process-test-classes - export + create true - org.hibernate.dialect.H2Dialect + org.hibernate.dialect.H2Dialect diff --git a/src/it/tutorials/envers/pom.xml b/src/it/tutorials/envers/pom.xml index 9980de39..69eeb5af 100644 --- a/src/it/tutorials/envers/pom.xml +++ b/src/it/tutorials/envers/pom.xml @@ -60,19 +60,19 @@ de.juplo - hibernate4-maven-plugin + hibernate-maven-plugin ${h4mp.version} process-test-classes - export + create true - org.hibernate.dialect.H2Dialect + org.hibernate.dialect.H2Dialect diff --git a/src/it/tutorials/osgi/managed-jpa/pom.xml b/src/it/tutorials/osgi/managed-jpa/pom.xml old mode 100755 new mode 100644 index 08ef2fea..1aa763c0 --- a/src/it/tutorials/osgi/managed-jpa/pom.xml +++ b/src/it/tutorials/osgi/managed-jpa/pom.xml @@ -70,12 +70,12 @@ de.juplo - hibernate4-maven-plugin + hibernate-maven-plugin ${h4mp.version} - export + create diff --git a/src/it/tutorials/osgi/unmanaged-jpa/pom.xml b/src/it/tutorials/osgi/unmanaged-jpa/pom.xml old mode 100755 new mode 100644 index 259540e5..24b84635 --- a/src/it/tutorials/osgi/unmanaged-jpa/pom.xml +++ b/src/it/tutorials/osgi/unmanaged-jpa/pom.xml @@ -76,12 +76,12 @@ de.juplo - hibernate4-maven-plugin + hibernate-maven-plugin ${h4mp.version} - export + create diff --git a/src/it/tutorials/osgi/unmanaged-native/pom.xml b/src/it/tutorials/osgi/unmanaged-native/pom.xml old mode 100755 new mode 100644 index cd337360..b83dea51 --- a/src/it/tutorials/osgi/unmanaged-native/pom.xml +++ b/src/it/tutorials/osgi/unmanaged-native/pom.xml @@ -84,12 +84,12 @@ de.juplo - hibernate4-maven-plugin + hibernate-maven-plugin ${h4mp.version} - export + create diff --git a/src/it/tutorials/schema-annotations.sql b/src/it/tutorials/schema-annotations.sql index 8448e8a2..48eb18ef 100644 --- a/src/it/tutorials/schema-annotations.sql +++ b/src/it/tutorials/schema-annotations.sql @@ -1,6 +1,4 @@ - drop table EVENTS if exists; - create table EVENTS ( id bigint not null, EVENT_DATE timestamp, diff --git a/src/it/tutorials/schema-basic.sql b/src/it/tutorials/schema-basic.sql index 4da1a3c1..c5e2c0e7 100644 --- a/src/it/tutorials/schema-basic.sql +++ b/src/it/tutorials/schema-basic.sql @@ -1,6 +1,4 @@ - drop table EVENTS if exists; - create table EVENTS ( EVENT_ID bigint not null, EVENT_DATE timestamp, diff --git a/src/it/tutorials/schema-entitymanager.sql b/src/it/tutorials/schema-entitymanager.sql index 8448e8a2..48eb18ef 100644 --- a/src/it/tutorials/schema-entitymanager.sql +++ b/src/it/tutorials/schema-entitymanager.sql @@ -1,6 +1,4 @@ - drop table EVENTS if exists; - create table EVENTS ( id bigint not null, EVENT_DATE timestamp, diff --git a/src/it/tutorials/schema-envers.sql b/src/it/tutorials/schema-envers.sql index 44643fa8..ecec80ef 100644 --- a/src/it/tutorials/schema-envers.sql +++ b/src/it/tutorials/schema-envers.sql @@ -1,10 +1,4 @@ - drop table EVENTS if exists; - - drop table EVENTS_AUD if exists; - - drop table REVINFO if exists; - create table EVENTS ( id bigint not null, EVENT_DATE timestamp, @@ -28,6 +22,6 @@ ); alter table EVENTS_AUD - add constraint FK_3hegaqrrpmx0jj0c8qacjtira + add constraint FK5cembm6xahf542q8e4h0pq2t1 foreign key (REV) references REVINFO; diff --git a/src/it/tutorials/schema-osgi-managed-jpa.sql b/src/it/tutorials/schema-osgi-managed-jpa.sql index 66738bb5..e69de29b 100644 --- a/src/it/tutorials/schema-osgi-managed-jpa.sql +++ b/src/it/tutorials/schema-osgi-managed-jpa.sql @@ -1,8 +0,0 @@ - - drop table DataPoint if exists; - - create table DataPoint ( - id bigint generated by default as identity, - name varchar(255), - primary key (id) - ); diff --git a/src/it/tutorials/schema-osgi-unmanaged-jpa.sql b/src/it/tutorials/schema-osgi-unmanaged-jpa.sql index 66738bb5..ef982198 100644 --- a/src/it/tutorials/schema-osgi-unmanaged-jpa.sql +++ b/src/it/tutorials/schema-osgi-unmanaged-jpa.sql @@ -1,6 +1,4 @@ - drop table DataPoint if exists; - create table DataPoint ( id bigint generated by default as identity, name varchar(255), diff --git a/src/it/tutorials/schema-osgi-unmanaged-native.sql b/src/it/tutorials/schema-osgi-unmanaged-native.sql index 37165353..9f02ba42 100644 --- a/src/it/tutorials/schema-osgi-unmanaged-native.sql +++ b/src/it/tutorials/schema-osgi-unmanaged-native.sql @@ -1,12 +1,8 @@ - drop table DataPoint if exists; - - drop table DataPoint_AUD if exists; - - drop table REVINFO if exists; + create sequence hibernate_sequence start with 1 increment by 1; create table DataPoint ( - id bigint generated by default as identity, + id bigint not null, name varchar(255), primary key (id) ); @@ -26,6 +22,6 @@ ); alter table DataPoint_AUD - add constraint FK_7pdslro8w1n74eqwmorrn0hnb + add constraint FK43jw6b5mtbfxur0xhyjxynbea foreign key (REV) references REVINFO; diff --git a/src/main/java/de/juplo/plugins/hibernate/AbstractSchemaMojo.java b/src/main/java/de/juplo/plugins/hibernate/AbstractSchemaMojo.java new file mode 100644 index 00000000..6c8a2818 --- /dev/null +++ b/src/main/java/de/juplo/plugins/hibernate/AbstractSchemaMojo.java @@ -0,0 +1,949 @@ +package de.juplo.plugins.hibernate; + + +import com.pyx4j.log4j.MavenLogAppender; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.net.URLClassLoader; +import java.security.NoSuchAlgorithmException; +import java.util.Collections; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedList; +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.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.selector.spi.StrategySelector; +import org.hibernate.boot.spi.MetadataImplementor; +import static org.hibernate.cfg.AvailableSettings.DIALECT; +import static org.hibernate.cfg.AvailableSettings.DRIVER; +import static org.hibernate.cfg.AvailableSettings.IMPLICIT_NAMING_STRATEGY; +import static org.hibernate.cfg.AvailableSettings.PASS; +import static org.hibernate.cfg.AvailableSettings.PHYSICAL_NAMING_STRATEGY; +import static org.hibernate.cfg.AvailableSettings.USER; +import static org.hibernate.cfg.AvailableSettings.URL; +import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider; +import org.hibernate.internal.util.config.ConfigurationException; +import static org.hibernate.jpa.AvailableSettings.JDBC_DRIVER; +import static org.hibernate.jpa.AvailableSettings.JDBC_PASSWORD; +import static org.hibernate.jpa.AvailableSettings.JDBC_URL; +import static org.hibernate.jpa.AvailableSettings.JDBC_USER; +import org.hibernate.jpa.boot.internal.ParsedPersistenceXmlDescriptor; +import org.hibernate.jpa.boot.internal.PersistenceXmlParser; +import org.hibernate.jpa.boot.spi.ProviderChecker; +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 EXPORT_SKIPPED_PROPERTY = "hibernate.export.skipped"; + + private final static Pattern SPLIT = Pattern.compile("[^,\\s]+"); + + + /** + * 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 + */ + String buildDirectory; + + /** + * Classes-Directory to scan. + *

+ * This parameter defaults to the maven build-output-directory for classes. + * Additionally, all dependencies are scanned for annotated classes. + * + * @parameter property="project.build.outputDirectory" + * @since 1.0 + */ + private String outputDirectory; + + /** + * Whether to scan test-classes too, or not. + *

+ * If this parameter is set to true the test-classes of the + * artifact will be scanned for hibernate-annotated classes additionally. + * + * @parameter property="hibernate.export.scan_testclasses" default-value="false" + * @since 1.0.1 + */ + private boolean scanTestClasses; + + /** + * 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. + *

md5s + * 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.export.scan_dependencies" default-value="compile" + * @since 1.0.3 + */ + private String scanDependencies; + + /** + * 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! + * + * @parameter property="project.build.testOutputDirectory" + * @since 1.0.2 + */ + private String testOutputDirectory; + + /** + * Skip execution + *

+ * If set to true, the execution is skipped. + *

+ * A skipped execution is signaled via the maven-property + * ${hibernate.export.skipped}. + *

+ * The execution is skipped automatically, if no modified or newly added + * annotated classes are found and the dialect was not changed. + * + * @parameter property="hibernate.skip" default-value="${maven.test.skip}" + * @since 1.0 + */ + private boolean skip; + + /** + * Force execution + *

+ * Force execution, even if no modified or newly added annotated classes + * where found and the dialect was not changed. + *

+ * skip takes precedence over force. + * + * @parameter property="hibernate.export.force" default-value="false" + * @since 1.0 + */ + private boolean force; + + /** + * 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; + + /** + * Hibernate dialect. + * + * @parameter property="hibernate.dialect" + * @since 1.0 + */ + private String dialect; + + /** + * Implicit naming strategy + * + * @parameter property=IMPLICIT_NAMING_STRATEGY + * @since 2.0 + */ + private String implicitNamingStrategy; + + /** + * Physical naming strategy + * + * @parameter property=PHYSICAL_NAMING_STRATEGY + * @since 2.0 + */ + private String physicalNamingStrategy; + + /** + * 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; + + + @Override + public final void execute() + throws + MojoFailureException, + MojoExecutionException + { + if (skip) + { + getLog().info("Execution of hibernate-maven-plugin was skipped!"); + project.getProperties().setProperty(EXPORT_SKIPPED_PROPERTY, "true"); + return; + } + + ModificationTracker tracker; + try + { + tracker = new ModificationTracker(buildDirectory, getLog()); + } + catch (NoSuchAlgorithmException e) + { + throw new MojoFailureException("Digest-Algorithm MD5 is missing!", e); + } + + SimpleConnectionProvider connectionProvider = + new SimpleConnectionProvider(getLog()); + + try + { + /** Start extended logging */ + MavenLogAppender.startPluginLog(this); + + /** Load checksums for old mapping and configuration */ + tracker.load(); + + /** Create a BootstrapServiceRegistry with special ClassLoader */ + BootstrapServiceRegistry bootstrapServiceRegitry = + new BootstrapServiceRegistryBuilder() + .applyClassLoader(createClassLoader()) + .build(); + ClassLoaderService classLoaderService = + bootstrapServiceRegitry.getService(ClassLoaderService.class); + + Properties properties = new Properties(); + ConfigLoader configLoader = new ConfigLoader(bootstrapServiceRegitry); + + /** Loading and merging configuration */ + properties.putAll(loadProperties(configLoader)); + properties.putAll(loadConfig(configLoader)); + properties.putAll(loadPersistenceUnit(classLoaderService, properties)); + + /** Overwriting/Completing configuration */ + configure(properties); + + /** Check configuration for modifications */ + if(tracker.check(properties)) + getLog().debug("Configuration has changed."); + else + getLog().debug("Configuration unchanged."); + + /** Configure Hibernate */ + StandardServiceRegistry serviceRegistry = + new StandardServiceRegistryBuilder(bootstrapServiceRegitry) + .applySettings(properties) + .addService(ConnectionProvider.class, connectionProvider) + .build(); + + /** Load Mappings */ + MetadataSources sources = new MetadataSources(serviceRegistry); + addAnnotatedClasses(sources, classLoaderService, tracker); + addMappings(sources, tracker); + + /** Skip execution, if mapping and configuration is unchanged */ + if (!tracker.modified()) + { + getLog().info( + "Mapping and configuration unchanged." + ); + if (force) + getLog().info("Schema generation is forced!"); + else + { + getLog().info("Skipping schema generation!"); + project.getProperties().setProperty(EXPORT_SKIPPED_PROPERTY, "true"); + return; + } + } + + + /** 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) + ) + ); + } + + build((MetadataImplementor)metadataBuilder.build()); + } + 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) + throws + MojoFailureException, + MojoExecutionException; + + + private URLClassLoader createClassLoader() throws MojoExecutionException + { + try + { + getLog().debug("Creating ClassLoader for project-dependencies..."); + List classpathFiles = project.getCompileClasspathElements(); + if (scanTestClasses) + classpathFiles.addAll(project.getTestClasspathElements()); + List urls = new LinkedList(); + 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()); + for (String pathElement : classpathFiles) + { + getLog().debug("Dependency: " + pathElement); + urls.add(new File(pathElement).toURI().toURL()); + } + return + new URLClassLoader( + urls.toArray(new URL[urls.size()]), + getClass().getClassLoader() + ); + } + 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 Map loadConfig(ConfigLoader configLoader) + throws MojoExecutionException + { + /** Try to read configuration from configuration-file */ + if (hibernateConfig == null) + { + try + { + return + configLoader + .loadConfigXmlResource("hibernate.cfg.xml") + .getConfigurationValues(); + } + catch (ConfigurationException e) + { + getLog().debug(e.getMessage()); + return Collections.EMPTY_MAP; + } + } + else + { + try + { + File file = new File(hibernateConfig); + if (file.exists()) + { + getLog().info("Reading configuration from file " + hibernateConfig + "..."); + return configLoader.loadConfigXmlFile(file).getConfigurationValues(); + } + else + return + configLoader + .loadConfigXmlResource(hibernateConfig) + .getConfigurationValues(); + } + catch (ConfigurationException e) + { + getLog().error("Error while reading configuration!", e); + throw new MojoExecutionException(e.getMessage()); + } + } + } + + private void configure(Properties properties) + throws MojoFailureException + { + /** Overwrite values from properties-file or set, if given */ + + if (driver != null) + { + if (properties.containsKey(DRIVER)) + getLog().debug("Overwriting property " + + DRIVER + "=" + properties.getProperty(DRIVER) + + " with the value " + driver + ); + else + getLog().debug("Using the value " + driver); + properties.setProperty(DRIVER, driver); + } + if (properties.getProperty(DRIVER) == null) + { + String driver = properties.getProperty(JDBC_DRIVER); + if (driver != null) + { + getLog().info(DRIVER + + " is not set. Borrow setting from " + + JDBC_DRIVER + + ": " + + driver); + properties.setProperty(DRIVER, driver); + } + } + + if (url != null) + { + if (properties.containsKey(URL)) + getLog().debug( + "Overwriting property " + + URL + "=" + properties.getProperty(URL) + + " with the value " + url + ); + else + getLog().debug("Using the value " + url); + properties.setProperty(URL, url); + } + if (properties.getProperty(URL) == null) + { + String url = properties.getProperty(JDBC_URL); + if (url != null) + { + getLog().info(URL + + " is not set. Borrow setting from " + + JDBC_URL + + ": " + + url); + properties.setProperty(URL, url); + } + } + + if (username != null) + { + if (properties.containsKey(USER)) + getLog().debug("Overwriting property " + + USER + "=" + properties.getProperty(USER) + + " with the value " + username + ); + else + getLog().debug("Using the value " + username); + properties.setProperty(USER, username); + } + if (properties.getProperty(USER) == null) + { + username = properties.getProperty(JDBC_USER); + if (username != null) + { + getLog().info(USER + + " is not set. Borrow setting from " + + JDBC_USER + + ": " + + username); + properties.setProperty(USER, username); + } + } + + if (password != null) + { + if (properties.containsKey(PASS)) + getLog().debug("Overwriting property " + + PASS + "=" + properties.getProperty(PASS) + + " with value " + password + ); + else + getLog().debug("Using value " + password + " for property " + PASS); + properties.setProperty(PASS, password); + } + if (properties.getProperty(PASS) == null) + { + password = properties.getProperty(JDBC_PASSWORD); + if (password != null) + { + getLog().info(PASS + + " is not set. Borrow setting from " + + JDBC_PASSWORD + + ": " + + password); + properties.setProperty(PASS, password); + } + } + + if (dialect != null) + { + if (properties.containsKey(DIALECT)) + getLog().debug( + "Overwriting property " + + DIALECT + "=" + properties.getProperty(DIALECT) + + " with value " + dialect + ); + else + getLog().debug( + "Using value " + dialect + " for property " + DIALECT + ); + properties.setProperty(DIALECT, dialect); + } + + if (implicitNamingStrategy != null ) + { + if ( properties.contains(IMPLICIT_NAMING_STRATEGY)) + getLog().debug( + "Overwriting property " + + IMPLICIT_NAMING_STRATEGY + "=" + properties.getProperty(IMPLICIT_NAMING_STRATEGY) + + " with value " + implicitNamingStrategy + ); + else + getLog().debug( + "Using value " + implicitNamingStrategy + " for property " + + IMPLICIT_NAMING_STRATEGY + + "Using value " + dialect + " for property " + DIALECT + ); + properties.setProperty(IMPLICIT_NAMING_STRATEGY, implicitNamingStrategy); + } + + if (physicalNamingStrategy != null ) + { + if ( properties.contains(PHYSICAL_NAMING_STRATEGY)) + getLog().debug( + "Overwriting property " + + PHYSICAL_NAMING_STRATEGY + "=" + properties.getProperty(PHYSICAL_NAMING_STRATEGY) + + " with value " + physicalNamingStrategy + ); + else + getLog().debug( + "Using value " + physicalNamingStrategy + " for property " + + PHYSICAL_NAMING_STRATEGY + + "Using value " + dialect + " for property " + DIALECT + ); + properties.setProperty(PHYSICAL_NAMING_STRATEGY, physicalNamingStrategy); + } + + if (properties.isEmpty()) + { + getLog().error("No properties set!"); + 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()); + } + + private void addMappings(MetadataSources sources, ModificationTracker tracker) + throws MojoFailureException + { + getLog().debug("Adding explicitly configured mappings..."); + if (mappings != null) + { + try + { + for (String filename : mappings.split("[\\s,]+")) + { + // First try the filename as absolute/relative path + File file = new File(filename); + if (!file.exists()) + { + // If the file was not found, search for it in the resource-directories + for (Resource resource : project.getResources()) + { + file = new File(resource.getDirectory() + File.separator + filename); + if (file.exists()) + break; + } + } + if (file.exists()) + { + if (file.isDirectory()) + // TODO: add support to read all mappings under a directory + throw new MojoFailureException(file.getAbsolutePath() + " is a directory"); + if (tracker.check(filename, new FileInputStream(file))) + getLog().debug("Found new or modified mapping-file: " + filename); + else + getLog().debug("mapping-file unchanged: " + filename); + + sources.addFile(file); + } + else + throw new MojoFailureException("File " + filename + " could not be found in any of the configured resource-directories!"); + } + } + catch (IOException e) + { + throw new MojoFailureException("Cannot calculate MD5 sums!", e); + } + } + } + + private void addAnnotatedClasses( + MetadataSources sources, + ClassLoaderService classLoaderService, + ModificationTracker tracker + ) + throws + MojoFailureException, + MojoExecutionException + + { + try + { + AnnotationDB db = new AnnotationDB(); + File dir; + + dir = new File(outputDirectory); + if (dir.exists()) + { + getLog().info("Scanning directory " + dir.getAbsolutePath() + " for annotated classes..."); + URL dirUrl = dir.toURI().toURL(); + db.scanArchives(dirUrl); + } + + if (scanTestClasses) + { + dir = new File(testOutputDirectory); + if (dir.exists()) + { + getLog().info("Scanning directory " + dir.getAbsolutePath() + " for annotated classes..."); + URL dirUrl = dir.toURI().toURL(); + db.scanArchives(dirUrl); + } + } + + if (scanDependencies != null) + { + Matcher matcher = SPLIT.matcher(scanDependencies); + while (matcher.find()) + { + getLog().info("Scanning dependencies for scope " + matcher.group()); + for (Artifact artifact : project.getDependencyArtifacts()) + { + if (!artifact.getScope().equalsIgnoreCase(matcher.group())) + continue; + if (artifact.getFile() == null) + { + getLog().warn("Cannot scan dependency " + artifact.getId() + ": no JAR-file available!"); + continue; + } + getLog().info("Scanning dependency " + artifact.getId() + " for annotated classes..."); + db.scanArchives(artifact.getFile().toURI().toURL()); + } + } + } + + Set classes = new HashSet(); + if (db.getAnnotationIndex().containsKey(Entity.class.getName())) + classes.addAll(db.getAnnotationIndex().get(Entity.class.getName())); + if (db.getAnnotationIndex().containsKey(MappedSuperclass.class.getName())) + classes.addAll(db.getAnnotationIndex().get(MappedSuperclass.class.getName())); + if (db.getAnnotationIndex().containsKey(Embeddable.class.getName())) + classes.addAll(db.getAnnotationIndex().get(Embeddable.class.getName())); + + Set packages = new HashSet(); + + for (String name : classes) + { + Class annotatedClass = classLoaderService.classForName(name); + String packageName = annotatedClass.getPackage().getName(); + if (!packages.contains(packageName)) + { + InputStream is = + annotatedClass.getResourceAsStream("package-info.class"); + if (is == null) + { + // No compiled package-info available: no package-level annotations! + getLog().debug("Package " + packageName + " is not annotated."); + } + else + { + if (tracker.check(packageName, is)) + getLog().debug("New or modified package: " + packageName); + else + getLog().debug("Unchanged package: " + packageName); + getLog().info("Adding annotated package " + packageName); + sources.addPackage(packageName); + } + packages.add(packageName); + } + String resourceName = annotatedClass.getName(); + resourceName = + resourceName.substring( + resourceName.lastIndexOf(".") + 1, + resourceName.length() + ) + ".class"; + InputStream is = + annotatedClass + .getResourceAsStream(resourceName); + if (tracker.check(name, is)) + getLog().debug("New or modified class: " + name); + else + getLog().debug("Unchanged class: " + name); + getLog().info("Adding annotated class " + annotatedClass); + sources.addAnnotatedClass(annotatedClass); + } + } + catch (Exception e) + { + getLog().error("Error while scanning!", e); + throw new MojoFailureException(e.getMessage()); + } + } + + private Properties loadPersistenceUnit( + ClassLoaderService classLoaderService, + Properties properties + ) + throws + MojoFailureException + { + PersistenceXmlParser parser = + new PersistenceXmlParser( + classLoaderService, + PersistenceUnitTransactionType.RESOURCE_LOCAL + ); + + List units = parser.doResolve(properties); + + if (persistenceUnit == null) + { + switch (units.size()) + { + case 0: + getLog().info("Found no META-INF/persistence.xml."); + return new Properties(); + case 1: + getLog().info("Using persistence-unit " + units.get(0).getName()); + return units.get(0).getProperties(); + default: + StringBuilder builder = new StringBuilder(); + builder.append("No name provided and multiple persistence units found: "); + Iterator it = units.iterator(); + builder.append(it.next().getName()); + while (it.hasNext()) + { + builder.append(", "); + builder.append(it.next().getName()); + } + builder.append('.'); + throw new MojoFailureException(builder.toString()); + } + } + + for (ParsedPersistenceXmlDescriptor unit : units) + { + getLog().debug("Found persistence-unit " + unit.getName()); + if (!unit.getName().equals(persistenceUnit)) + 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.getProperties(); + } + + throw new MojoFailureException("Could not find persistence-unit " + persistenceUnit); + } +} diff --git a/src/main/java/de/juplo/plugins/hibernate/CreateMojo.java b/src/main/java/de/juplo/plugins/hibernate/CreateMojo.java new file mode 100644 index 00000000..19078ea8 --- /dev/null +++ b/src/main/java/de/juplo/plugins/hibernate/CreateMojo.java @@ -0,0 +1,122 @@ +package de.juplo.plugins.hibernate; + +/* + * Copyright 2001-2005 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.io.File; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.MojoFailureException; +import org.hibernate.boot.spi.MetadataImplementor; +import org.hibernate.tool.hbm2ddl.SchemaExport; + + +/** + * Goal which extracts the hibernate-mapping-configuration and + * exports an according SQL-database-schema. + * + * @goal create + * @phase process-classes + * @threadSafe + * @requiresDependencyResolution runtime + */ +public class CreateMojo extends AbstractSchemaMojo +{ + /** + * Export the database-schma to the database. + * If set to false, only the SQL-script is created and the + * database is not touched. + * + * @parameter property="hibernate.export.export" default-value="true" + * @since 2.0 + */ + private boolean export; + + /** + * Create the catalog + * If set to false, only the SQL-script is created and the + * database is not touched. + * + * @parameter property=org.hibernate.cfg.AvailableSettings.HBM2DDL_IMPORT_FILES_SQL_EXTRACTOR default-value="false" + * @since 2.0 + */ + private boolean createNamespaces; // TODO handle in configure-Method + + /** + * Output file. + * + * @parameter property="hibernate.export.schema.filename" default-value="${project.build.directory}/schema.sql" + * @since 1.0 + */ + private String outputFile; + + /** + * Delimiter in output-file. + * + * @parameter property="hibernate.export.schema.delimiter" default-value=";" + * @since 1.0 + */ + private String delimiter; + + /** + * Format output-file. + * + * @parameter property="hibernate.export.schema.format" default-value="true" + * @since 1.0 + */ + private boolean format; + + + @Override + void build(MetadataImplementor metadata) + throws + MojoExecutionException, + MojoFailureException + { + SchemaExport schemaExport = new SchemaExport(metadata, createNamespaces); + schemaExport.setDelimiter(delimiter); + schemaExport.setFormat(format); + + File output = new File(outputFile); + + if (!output.isAbsolute()) + { + // Interpret relative file path relative to build directory + output = new File(buildDirectory, outputFile); + getLog().debug("Adjusted relative path, resulting path is " + output.getPath()); + } + + // Ensure that directory path for specified file exists + File outFileParentDir = output.getParentFile(); + if (null != outFileParentDir && !outFileParentDir.exists()) + { + try + { + getLog().info("Creating directory path for output file:" + outFileParentDir.getPath()); + outFileParentDir.mkdirs(); + } + catch (Exception e) + { + getLog().error("Error creating directory path for output file: " + e.getLocalizedMessage()); + } + } + + schemaExport.setOutputFile(output.getPath()); + schemaExport.execute(false, this.export, false, true); + + for (Object exception : schemaExport.getExceptions()) + getLog().error(exception.toString()); + } +} diff --git a/src/main/java/de/juplo/plugins/hibernate/ModificationTracker.java b/src/main/java/de/juplo/plugins/hibernate/ModificationTracker.java new file mode 100644 index 00000000..e03f78e9 --- /dev/null +++ b/src/main/java/de/juplo/plugins/hibernate/ModificationTracker.java @@ -0,0 +1,171 @@ +package de.juplo.plugins.hibernate; + + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.math.BigInteger; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Properties; +import java.util.Set; +import org.apache.maven.plugin.logging.Log; + + + +/** + * + * @author Kai Moritz + */ +public class ModificationTracker +{ + public final static String MD5S = "hibernate-generatedschema.md5s"; + + private Map properties; + private Map classes; + + private final Set propertyNames; + private final Set classNames; + + private boolean modified = false; + + private final File saved; + private final MessageDigest digest; + private final Log log; + + + ModificationTracker(String buildDirectory, Log log) + throws + NoSuchAlgorithmException + { + propertyNames = new HashSet(); + classNames = new HashSet(); + saved = new File(buildDirectory + File.separator + MD5S); + digest = java.security.MessageDigest.getInstance("MD5"); + this.log = log; + } + + + private String calculate(InputStream is) + throws + IOException + { + byte[] buffer = new byte[1024*4]; // copy data in 4MB-chunks + int i; + while((i = is.read(buffer)) > -1) + digest.update(buffer, 0, i); + is.close(); + byte[] bytes = digest.digest(); + BigInteger bi = new BigInteger(1, bytes); + return String.format("%0" + (bytes.length << 1) + "x", bi); + } + + private boolean check(Map values, String name, String value) + { + if (!values.containsKey(name) || !values.get(name).equals(value)) + { + values.put(name, value); + return true; + } + else + return false; + } + + + boolean check(String name, InputStream is) throws IOException + { + boolean result = check(classes, name, calculate(is)); + classNames.add(name); + modified |= result; + return result; + } + + boolean check(String name, String property) + { + boolean result = check(properties, name, property); + propertyNames.add(name); + modified |= result; + return result; + } + + boolean check(Properties properties) + { + boolean result = false; + for (String name : properties.stringPropertyNames()) + result |= check(name, properties.getProperty(name)); + return result; + } + + + boolean modified() + { + modified |= !propertyNames.containsAll(properties.keySet()); + modified |= !properties.keySet().containsAll(propertyNames); + modified |= !classNames.containsAll(classes.keySet()); + modified |= !classes.keySet().containsAll(classNames); + return modified; + } + + + void load() + { + if (saved.isFile() && saved.length() > 0) + { + try + { + FileInputStream fis = new FileInputStream(saved); + ObjectInputStream ois = new ObjectInputStream(fis); + properties = (HashMap)ois.readObject(); + classes = (HashMap)ois.readObject(); + ois.close(); + } + catch (Exception e) + { + properties = new HashMap(); + classes = new HashMap(); + log.warn("Cannot read md5s from saved: " + e); + } + } + else + { + properties = new HashMap(); + classes = new HashMap(); + try + { + saved.createNewFile(); + } + catch (IOException e) + { + log.debug("Cannot create file \"" + saved.getPath() + "\" for md5s: " + e); + } + } + } + + void save() + { + if (!modified) + return; + + /** Write md5-sums for annotated classes to file */ + try + { + FileOutputStream fos = new FileOutputStream(saved); + ObjectOutputStream oos = new ObjectOutputStream(fos); + oos.writeObject(properties); + oos.writeObject(classes); + oos.close(); + fos.close(); + } + catch (Exception e) + { + log.error("Cannot write md5-sums to file: " + e); + } + } +} diff --git a/src/main/java/de/juplo/plugins/hibernate/SimpleConnectionProvider.java b/src/main/java/de/juplo/plugins/hibernate/SimpleConnectionProvider.java new file mode 100644 index 00000000..36fe5614 --- /dev/null +++ b/src/main/java/de/juplo/plugins/hibernate/SimpleConnectionProvider.java @@ -0,0 +1,249 @@ +package de.juplo.plugins.hibernate; + +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.Properties; +import java.util.logging.Logger; +import org.apache.maven.plugin.MojoFailureException; +import org.apache.maven.plugin.logging.Log; +import static org.eclipse.aether.repository.AuthenticationContext.PASSWORD; +import static org.eclipse.aether.repository.AuthenticationContext.USERNAME; +import org.hibernate.boot.registry.classloading.spi.ClassLoaderService; +import static org.hibernate.cfg.AvailableSettings.DRIVER; +import static org.hibernate.cfg.AvailableSettings.PASS; +import static org.hibernate.cfg.AvailableSettings.URL; +import static org.hibernate.cfg.AvailableSettings.USER; +import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider; +import static org.hibernate.jpa.AvailableSettings.JDBC_DRIVER; +import static org.hibernate.jpa.AvailableSettings.JDBC_PASSWORD; +import static org.hibernate.jpa.AvailableSettings.JDBC_URL; +import static org.hibernate.jpa.AvailableSettings.JDBC_USER; + +/** + * + * @author Kai Moritz + */ +class SimpleConnectionProvider implements ConnectionProvider +{ + private final Log log; + + private Connection connection; + + + SimpleConnectionProvider(Log log) + { + this.log = log; + } + + + void open(ClassLoaderService classLoaderService, Properties properties) + throws + MojoFailureException + { + + String driver = (String) + (properties.containsKey(DRIVER) + ? properties.getProperty(DRIVER) + : properties.getProperty(JDBC_DRIVER) + ); + String url = (String) + (properties.containsKey(URL) + ? properties.getProperty(URL) + : properties.getProperty(JDBC_URL) + ); + String user = (String) + (properties.containsKey(USER) + ? properties.getProperty(USER) + : properties.getProperty(JDBC_USER) + ); + String password = (String) + (properties.containsKey(PASS) + ? properties.getProperty(PASS) + : properties.getProperty(JDBC_PASSWORD) + ); + + if (driver == null || url == null || user == null) + { + log.info("No connection opened, because connection information is incomplete"); + log.info("Driver-Class: " + driver); + log.info("URL: " + url); + log.info("User: " + user); + return; + } + + try + { + Class driverClass = classLoaderService.classForName(driver); + + log.debug("Registering JDBC-driver " + driverClass.getName()); + DriverManager + .registerDriver(new DriverProxy((Driver) driverClass.newInstance())); + + log.debug( + "Opening JDBC-connection to " + properties.getProperty(URL) + + " as " + properties.getProperty(USERNAME) + + " with password " + properties.getProperty(PASSWORD) + ); + + connection = DriverManager.getConnection(url, user, password); + } + catch (Exception e) + { + throw new MojoFailureException("Could not open the JDBC-connection", e); + } + } + + void close() + { + if (connection == null) + return; + + log.debug("Closing the JDBC-connection."); + try + { + connection.close(); + } + catch (SQLException e) + { + log.error("Error while closing the JDBC-connection: " + e.getMessage()); + } + } + + @Override + public Connection getConnection() throws SQLException + { + log.debug("Connection aquired."); + + if (connection == null) + throw new SQLException("No connection available, because of insufficient connection information!"); + + return connection; + } + + @Override + public void closeConnection(Connection conn) throws SQLException + { + log.debug("Connection released"); + } + + @Override + public boolean supportsAggressiveRelease() + { + return false; + } + + @Override + public boolean isUnwrappableAs(Class unwrapType) + { + return false; + } + + @Override + public T unwrap(Class unwrapType) + { + throw new UnsupportedOperationException("Not supported."); + } + + /** + * Needed, because DriverManager won't pick up drivers, that were not + * loaded by the system-classloader! + * See: + * http://stackoverflow.com/questions/288828/how-to-use-a-jdbc-driver-fromodifiedm-an-arbitrary-location + */ + static final class DriverProxy implements Driver + { + private final Driver target; + + DriverProxy(Driver target) + { + if (target == null) + throw new NullPointerException(); + this.target = target; + } + + public java.sql.Driver getTarget() + { + return target; + } + + @Override + public boolean acceptsURL(String url) throws SQLException + { + return target.acceptsURL(url); + } + + @Override + public java.sql.Connection connect( + String url, + java.util.Properties info + ) + throws + SQLException + { + return target.connect(url, info); + } + + @Override + public int getMajorVersion() + { + return target.getMajorVersion(); + } + + @Override + public int getMinorVersion() + { + return target.getMinorVersion(); + } + + @Override + public DriverPropertyInfo[] getPropertyInfo( + String url, + Properties info + ) + throws + SQLException + { + return target.getPropertyInfo(url, info); + } + + @Override + public boolean jdbcCompliant() + { + return target.jdbcCompliant(); + } + + /** + * This Method cannot be annotated with @Override, becaus the plugin + * will not compile then under Java 1.6! + */ + public Logger getParentLogger() throws SQLFeatureNotSupportedException + { + throw new SQLFeatureNotSupportedException("Not supported, for backward-compatibility with Java 1.6"); + } + + @Override + public String toString() + { + return "Proxy: " + target; + } + + @Override + public int hashCode() + { + return target.hashCode(); + } + + @Override + public boolean equals(Object obj) + { + if (!(obj instanceof DriverProxy)) + return false; + DriverProxy other = (DriverProxy) obj; + return this.target.equals(other.target); + } + } +} diff --git a/src/main/java/de/juplo/plugins/hibernate4/Hbm2DdlMojo.java b/src/main/java/de/juplo/plugins/hibernate4/Hbm2DdlMojo.java deleted file mode 100644 index f8c06344..00000000 --- a/src/main/java/de/juplo/plugins/hibernate4/Hbm2DdlMojo.java +++ /dev/null @@ -1,1307 +0,0 @@ -package de.juplo.plugins.hibernate4; - -/* - * Copyright 2001-2005 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import com.pyx4j.log4j.MavenLogAppender; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.math.BigInteger; -import java.net.URL; -import java.net.URLClassLoader; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.sql.Driver; -import java.sql.DriverPropertyInfo; -import java.sql.SQLException; -import java.sql.SQLFeatureNotSupportedException; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedHashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Properties; -import java.util.Set; -import java.util.TreeSet; -import java.util.logging.Logger; -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.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; -import org.scannotation.AnnotationDB; - - -/** - * Goal which extracts the hibernate-mapping-configuration and - * exports an according SQL-database-schema. - * - * @goal export - * @phase process-classes - * @threadSafe - * @requiresDependencyResolution runtime - */ -public class Hbm2DdlMojo extends AbstractMojo -{ - public final static String EXPORT_SKIPPED_PROPERTY = "hibernate.export.skipped"; - - public final static String DRIVER_CLASS = "hibernate.connection.driver_class"; - public final static String URL = "hibernate.connection.url"; - public final static String USERNAME = "hibernate.connection.username"; - public final static String PASSWORD = "hibernate.connection.password"; - public final static String DIALECT = "hibernate.dialect"; - public final static String NAMING_STRATEGY="hibernate.ejb.naming_strategy"; - public final static String ENVERS = "hibernate.export.envers"; - - public final static String JPA_DRIVER = "javax.persistence.jdbc.driver"; - public final static String JPA_URL = "javax.persistence.jdbc.url"; - public final static String JPA_USERNAME = "javax.persistence.jdbc.user"; - public final static String JPA_PASSWORD = "javax.persistence.jdbc.password"; - - public final static String MD5S = "hibernate4-generatedschema.md5s"; - - private final static Pattern split = Pattern.compile("[^,\\s]+"); - - - /** - * 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; - - /** - * Classes-Directory to scan. - *

- * This parameter defaults to the maven build-output-directory for classes. - * Additionally, all dependencies are scanned for annotated classes. - * - * @parameter property="project.build.outputDirectory" - * @since 1.0 - */ - private String outputDirectory; - - /** - * Whether to scan test-classes too, or not. - *

- * If this parameter is set to true the test-classes of the - * artifact will be scanned for hibernate-annotated classes additionally. - * - * @parameter property="hibernate.export.scan_testclasses" default-value="false" - * @since 1.0.1 - */ - private boolean scanTestClasses; - - /** - * 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.export.scan_dependencies" default-value="compile" - * @since 1.0.3 - */ - private String scanDependencies; - - /** - * 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! - * - * @parameter property="project.build.testOutputDirectory" - * @since 1.0.2 - */ - private String testOutputDirectory; - - /** - * Skip execution - *

- * If set to true, the execution is skipped. - *

- * A skipped execution is signaled via the maven-property - * ${hibernate.export.skipped}. - *

- * The execution is skipped automatically, if no modified or newly added - * annotated classes are found and the dialect was not changed. - * - * @parameter property="hibernate.skip" default-value="${maven.test.skip}" - * @since 1.0 - */ - private boolean skip; - - /** - * Force execution - *

- * Force execution, even if no modified or newly added annotated classes - * where found and the dialect was not changed. - *

- * skip takes precedence over force. - * - * @parameter property="hibernate.export.force" default-value="false" - * @since 1.0 - */ - private boolean force; - - /** - * SQL-Driver name. - * - * @parameter property="hibernate.connection.driver_class" - * @since 1.0 - */ - private String driverClassName; - - /** - * 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; - - /** - * Hibernate dialect. - * - * @parameter property="hibernate.dialect" - * @since 1.0 - */ - private String hibernateDialect; - - /** - * Hibernate Naming Strategy - * - * @parameter property="hibernate.ejb.naming_strategy" - * @since 1.0.2 - */ - private String hibernateNamingStrategy; - - /** - * Path to Hibernate properties file. - * If this parameter is not set the plugin will try to load the configuration - * from a file hibernate.properties on the classpath. The - * test-classpath takes precedence. - * - * @parameter - * @since 1.0 - */ - private String hibernateProperties; - - /** - * Path to Hibernate configuration file (.cfg.xml). - * Settings in this file will overwrite settings in the properties file. - * If this parameter is not set the plugin will try to load the configuration - * from a file hibernate.cfg.xml on the classpath. The - * test-classpath takes precedence. - * - * @parameter - * @since 1.1.0 - */ - private String hibernateConfig; - - /** - * Name of the persistence-unit. - * If there is only one persistence-unit available, that unit will be used - * automatically. - * 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 hibernateMapping; - - /** - * Target of execution: - *

    - *
  • NONE only export schema to SQL-script (forces execution, signals skip)
  • - *
  • EXPORT create database (DEFAULT!). forces execution, signals skip)
  • - *
  • SCRIPT export schema to SQL-script and print it to STDOUT
  • - *
  • BOTH
  • - *
- * - * A database connection is only needed for EXPORT and BOTH, but a - * Hibernate-Dialect must always be chosen. - * - * @parameter property="hibernate.export.target" default-value="EXPORT" - * @since 1.0 - */ - private String target; - - /** - * Type of execution. - *
    - *
  • NONE do nothing - just validate the configuration
  • - *
  • CREATE create database-schema
  • - *
  • DROP drop database-schema
  • - *
  • BOTH (DEFAULT!)
  • - *
- * - * If NONE is choosen, no databaseconnection is needed. - * - * @parameter property="hibernate.export.type" default-value="BOTH" - * @since 1.0 - */ - private String type; - - /** - * Output file. - * - * @parameter property="hibernate.export.schema.filename" default-value="${project.build.directory}/schema.sql" - * @since 1.0 - */ - private String outputFile; - - /** - * Delimiter in output-file. - * - * @parameter property="hibernate.export.schema.delimiter" default-value=";" - * @since 1.0 - */ - private String delimiter; - - /** - * Format output-file. - * - * @parameter property="hibernate.export.schema.format" default-value="true" - * @since 1.0 - */ - private boolean format; - - /** - * Generate envers schema for auditing tables. - * - * @parameter property="hibernate.export.envers" default-value="true" - * @since 1.0.3 - */ - private boolean envers; - - - @Override - public void execute() - throws - MojoFailureException, - MojoExecutionException - { - if (skip) - { - getLog().info("Execution of hibernate4-maven-plugin:export was skipped!"); - project.getProperties().setProperty(EXPORT_SKIPPED_PROPERTY, "true"); - return; - } - - Map md5s; - boolean modified = false; - File saved = new File(buildDirectory + File.separator + MD5S); - - if (saved.isFile() && saved.length() > 0) - { - try - { - FileInputStream fis = new FileInputStream(saved); - ObjectInputStream ois = new ObjectInputStream(fis); - md5s = (HashMap)ois.readObject(); - ois.close(); - } - catch (Exception e) - { - md5s = new HashMap(); - getLog().warn("Cannot read timestamps from saved: " + e); - } - } - else - { - md5s = new HashMap(); - try - { - saved.createNewFile(); - } - catch (IOException e) - { - getLog().debug("Cannot create file \"" + saved.getPath() + "\" for timestamps: " + e); - } - } - - URLClassLoader classLoader = null; - try - { - getLog().debug("Creating ClassLoader for project-dependencies..."); - List classpathFiles = project.getCompileClasspathElements(); - if (scanTestClasses) - classpathFiles.addAll(project.getTestClasspathElements()); - List urls = new LinkedList(); - 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()); - for (String pathElement : classpathFiles) - { - getLog().debug("Dependency: " + pathElement); - urls.add(new File(pathElement).toURI().toURL()); - } - classLoader = - new URLClassLoader( - urls.toArray(new URL[urls.size()]), - getClass().getClassLoader() - ); - } - catch (Exception e) - { - getLog().error("Error while creating ClassLoader!", e); - throw new MojoExecutionException(e.getMessage()); - } - - Set> classes = - new TreeSet>( - new Comparator>() { - @Override - public int compare(Class a, Class b) - { - return a.getName().compareTo(b.getName()); - } - } - ); - - try - { - AnnotationDB db = new AnnotationDB(); - File dir = new File(outputDirectory); - if (dir.exists()) - { - getLog().info("Scanning directory " + outputDirectory + " for annotated classes..."); - URL dirUrl = dir.toURI().toURL(); - db.scanArchives(dirUrl); - } - if (scanTestClasses) - { - dir = new File(testOutputDirectory); - if (dir.exists()) - { - getLog().info("Scanning directory " + testOutputDirectory + " for annotated classes..."); - URL dirUrl = dir.toURI().toURL(); - db.scanArchives(dirUrl); - } - } - if (scanDependencies != null) - { - Matcher matcher = split.matcher(scanDependencies); - while (matcher.find()) - { - getLog().info("Scanning dependencies for scope " + matcher.group()); - for (Artifact artifact : project.getDependencyArtifacts()) - { - if (!artifact.getScope().equalsIgnoreCase(matcher.group())) - continue; - if (artifact.getFile() == null) - { - getLog().warn( - "Cannot scan dependency " + - artifact.getId() + - ": no JAR-file available!" - ); - continue; - } - getLog().info( - "Scanning dependency " + - artifact.getId() + - " for annotated classes..." - ); - db.scanArchives(artifact.getFile().toURI().toURL()); - } - } - } - - Set classNames = new HashSet(); - if (db.getAnnotationIndex().containsKey(Entity.class.getName())) - classNames.addAll(db.getAnnotationIndex().get(Entity.class.getName())); - if (db.getAnnotationIndex().containsKey(MappedSuperclass.class.getName())) - classNames.addAll(db.getAnnotationIndex().get(MappedSuperclass.class.getName())); - if (db.getAnnotationIndex().containsKey(Embeddable.class.getName())) - classNames.addAll(db.getAnnotationIndex().get(Embeddable.class.getName())); - - MessageDigest digest = java.security.MessageDigest.getInstance("MD5"); - for (String name : classNames) - { - Class annotatedClass = classLoader.loadClass(name); - classes.add(annotatedClass); - String resourceName = annotatedClass.getName(); - resourceName = resourceName.substring(resourceName.lastIndexOf(".") + 1, resourceName.length()) + ".class"; - InputStream is = - annotatedClass - .getResourceAsStream(resourceName); - byte[] buffer = new byte[1024*4]; // copy data in 4MB-chunks - int i; - while((i = is.read(buffer)) > -1) - digest.update(buffer, 0, i); - is.close(); - byte[] bytes = digest.digest(); - BigInteger bi = new BigInteger(1, bytes); - String newMd5 = String.format("%0" + (bytes.length << 1) + "x", bi); - String oldMd5 = !md5s.containsKey(name) ? "" : md5s.get(name); - if (!newMd5.equals(oldMd5)) - { - getLog().debug("Found new or modified annotated class: " + name); - modified = true; - md5s.put(name, newMd5); - } - else - { - getLog().debug(oldMd5 + " -> class unchanged: " + name); - } - } - } - catch (ClassNotFoundException e) - { - getLog().error("Error while adding annotated classes!", e); - throw new MojoExecutionException(e.getMessage()); - } - catch (Exception e) - { - getLog().error("Error while scanning!", e); - throw new MojoFailureException(e.getMessage()); - } - - - ValidationConfiguration config = new ValidationConfiguration(); - // Clear unused system-properties - config.setProperties(new Properties()); - - - ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader(); - StandardServiceRegistryImpl registry = null; - MavenLogAppender.startPluginLog(this); - - try - { - /** - * Change class-loader of current thread, so that hibernate can - * see all dependencies! - */ - Thread.currentThread().setContextClassLoader(classLoader); - - - /** Try to read configuration from properties-file */ - try - { - if (hibernateProperties == null) - { - URL url = classLoader.findResource("hibernate.properties"); - if (url == null) - { - getLog().info("No hibernate.properties on the classpath!"); - } - else - { - getLog().info("Reading settings from hibernate.properties on the classpath."); - Properties properties = new Properties(); - properties.load(url.openStream()); - config.setProperties(properties); - } - } - else - { - File file = new File(hibernateProperties); - if (file.exists()) - { - getLog().info("Reading settings from file " + hibernateProperties + "..."); - Properties properties = new Properties(); - properties.load(new FileInputStream(file)); - config.setProperties(properties); - } - else - getLog().info("No hibernate-properties-file found! (Checked path: " + hibernateProperties + ")"); - } - } - catch (IOException e) - { - getLog().error("Error while reading properties!", e); - throw new MojoExecutionException(e.getMessage()); - } - - /** Try to read configuration from configuration-file */ - try - { - if (hibernateConfig == null) - { - URL url = classLoader.findResource("hibernate.cfg.xml"); - if (url == null) - { - getLog().info("No hibernate.cfg.xml on the classpath!"); - } - else - { - getLog().info("Reading settings from hibernate.cfg.xml on the classpath."); - config.configure(url); - } - } - else - { - File file = new File(hibernateConfig); - if (file.exists()) - { - getLog().info("Reading configuration from file " + hibernateConfig + "..."); - config.configure(file); - } - else - getLog().info("No hibernate-configuration-file found! (Checked path: " + hibernateConfig + ")"); - } - } - catch (Exception e) - { - getLog().error("Error while reading configuration!", e); - throw new MojoExecutionException(e.getMessage()); - } - - ParsedPersistenceXmlDescriptor persistenceUnitDescriptor = - getPersistenceUnitDescriptor( - persistenceUnit, - config.getProperties(), - new MavenProjectClassLoaderService(classLoader) - ); - if (persistenceUnitDescriptor != null) - config.setProperties(persistenceUnitDescriptor.getProperties()); - - - /** Overwrite values from properties-file or set, if given */ - - if (driverClassName != null) - { - if (config.getProperties().containsKey(DRIVER_CLASS)) - getLog().debug( - "Overwriting property " + - DRIVER_CLASS + "=" + config.getProperty(DRIVER_CLASS) + - " with the value " + driverClassName - ); - else - getLog().debug("Using the value " + driverClassName); - config.setProperty(DRIVER_CLASS, driverClassName); - } - if (config.getProperty(DRIVER_CLASS) == null) - { - String driver = config.getProperty(JPA_DRIVER); - if (driver != null) - { - getLog().info( - DRIVER_CLASS + - " is not set. Borrow setting from " + - JPA_DRIVER + - ": " + - driver); - config.setProperty(DRIVER_CLASS, driver); - } - } - - if (url != null) - { - if (config.getProperties().containsKey(URL)) - getLog().debug( - "Overwriting property " + - URL + "=" + config.getProperty(URL) + - " with the value " + url - ); - else - getLog().debug("Using the value " + url); - config.setProperty(URL, url); - } - if (config.getProperty(URL) == null) - { - String url = config.getProperty(JPA_URL); - if (url != null) - { - getLog().info( - URL + - " is not set. Borrow setting from " + - JPA_URL + - ": " + - url); - config.setProperty(URL, url); - } - } - - if (username != null) - { - if (config.getProperties().containsKey(USERNAME)) - getLog().debug( - "Overwriting property " + - USERNAME + "=" + config.getProperty(USERNAME) + - " with the value " + username - ); - else - getLog().debug("Using the value " + username); - config.setProperty(USERNAME, username); - } - if (config.getProperty(USERNAME) == null) - { - String username = config.getProperty(JPA_USERNAME); - if (username != null) - { - getLog().info( - USERNAME + - " is not set. Borrow setting from " + - JPA_USERNAME + - ": " + - username); - config.setProperty(USERNAME, username); - } - } - - if (password != null) - { - if (config.getProperties().containsKey(PASSWORD)) - getLog().debug( - "Overwriting property " + - PASSWORD + "=" + config.getProperty(PASSWORD) + - " with value " + password - ); - else - getLog().debug("Using value " + password + " for property " + PASSWORD); - config.setProperty(PASSWORD, password); - } - if (config.getProperty(PASSWORD) == null) - { - String password = config.getProperty(JPA_PASSWORD); - if (password != null) - { - getLog().info( - PASSWORD + - " is not set. Borrow setting from " + - JPA_PASSWORD + - ": " + - password); - config.setProperty(PASSWORD, password); - } - } - - if (hibernateDialect != null) - { - if (config.getProperties().containsKey(DIALECT)) - getLog().debug( - "Overwriting property " + - DIALECT + "=" + config.getProperty(DIALECT) + - " with value " + hibernateDialect - ); - else - getLog().debug( - "Using value " + hibernateDialect + " for property " + DIALECT - ); - config.setProperty(DIALECT, hibernateDialect); - } - - if ( hibernateNamingStrategy != null ) - { - if ( config.getProperties().contains(NAMING_STRATEGY)) - getLog().debug( - "Overwriting property " + - NAMING_STRATEGY + "=" + config.getProperty(NAMING_STRATEGY) + - " with value " + hibernateNamingStrategy - ); - else - getLog().debug( - "Using value " + hibernateNamingStrategy + " for property " + - NAMING_STRATEGY - ); - config.setProperty(NAMING_STRATEGY, hibernateNamingStrategy); - } - - /** The generated SQL varies with the dialect! */ - if (md5s.containsKey(DIALECT)) - { - String dialect = config.getProperty(DIALECT); - if (md5s.get(DIALECT).equals(dialect)) - getLog().debug("SQL-dialect unchanged."); - else - { - modified = true; - if (dialect == null) - { - getLog().debug("SQL-dialect was unset."); - md5s.remove(DIALECT); - } - else - { - getLog().debug("SQL-dialect changed: " + dialect); - md5s.put(DIALECT, dialect); - } - } - } - else - { - String dialect = config.getProperty(DIALECT); - if (dialect != null) - { - modified = true; - md5s.put(DIALECT, config.getProperty(DIALECT)); - } - } - - /** The generated SQL varies with the envers-configuration */ - if (md5s.get(ENVERS) != null) - { - if (md5s.get(ENVERS).equals(Boolean.toString(envers))) - getLog().debug("Envers-Configuration unchanged. Enabled: " + envers); - else - { - getLog().debug("Envers-Configuration changed. Enabled: " + envers); - modified = true; - md5s.put(ENVERS, Boolean.toString(envers)); - } - } - else - { - modified = true; - md5s.put(ENVERS, Boolean.toString(envers)); - } - - if (config.getProperties().isEmpty()) - { - getLog().error("No properties set!"); - throw new MojoFailureException("Hibernate configuration is missing!"); - } - - getLog().info("Gathered hibernate-configuration (turn on debugging for details):"); - for (Entry entry : config.getProperties().entrySet()) - getLog().info(" " + entry.getKey() + " = " + entry.getValue()); - - - getLog().debug("Adding explicitly configured mappings..."); - if (hibernateMapping != null) - { - try - { - MessageDigest digest = java.security.MessageDigest.getInstance("MD5"); - for (String filename : hibernateMapping.split("[\\s,]+")) - { - // First try the filename as absolute/relative path - File file = new File(filename); - if (!file.exists()) - { - // If the file was not found, search for it in the resource-directories - for (Resource resource : project.getResources()) - { - file = new File(resource.getDirectory() + File.separator + filename); - if (file.exists()) - break; - } - } - if (file != null && file.exists()) - { - InputStream is = new FileInputStream(file); - byte[] buffer = new byte[1024*4]; // copy data in 4MB-chunks - int i; - while((i = is.read(buffer)) > -1) - digest.update(buffer, 0, i); - is.close(); - byte[] bytes = digest.digest(); - BigInteger bi = new BigInteger(1, bytes); - String newMd5 = String.format("%0" + (bytes.length << 1) + "x", bi); - String oldMd5 = !md5s.containsKey(filename) ? "" : md5s.get(filename); - if (!newMd5.equals(oldMd5)) - { - getLog().debug("Found new or modified mapping-file: " + filename); - modified = true; - md5s.put(filename, newMd5); - } - else - { - getLog().debug(oldMd5 + " -> mapping-file unchanged: " + filename); - } - getLog().debug("Adding mappings from XML-configurationfile: " + file); - config.addFile(file); - } - else - throw new MojoFailureException("File " + filename + " could not be found in any of the configured resource-directories!"); - } - } - catch (NoSuchAlgorithmException e) - { - throw new MojoFailureException("Cannot calculate MD5 sums!", e); - } - catch (FileNotFoundException e) - { - throw new MojoFailureException("Cannot calculate MD5 sums!", e); - } - catch (IOException e) - { - throw new MojoFailureException("Cannot calculate MD5 sums!", e); - } - } - - getLog().debug("Adding annotated classes to hibernate-mapping-configuration..."); - // build annotated packages - Set packages = new HashSet(); - for (Class annotatedClass : classes) - { - String packageName = annotatedClass.getPackage().getName(); - if (!packages.contains(packageName)) - { - getLog().debug("Add package " + packageName); - packages.add(packageName); - config.addPackage(packageName); - getLog().debug("type definintions" + config.getTypeDefs()); - } - getLog().debug("Class " + annotatedClass); - config.addAnnotatedClass(annotatedClass); - } - - Target target = null; - try - { - target = Target.valueOf(this.target.toUpperCase()); - } - catch (IllegalArgumentException e) - { - getLog().error("Invalid value for configuration-option \"target\": " + this.target); - getLog().error("Valid values are: NONE, SCRIPT, EXPORT, BOTH"); - throw new MojoExecutionException("Invalid value for configuration-option \"target\""); - } - Type type = null; - try - { - type = Type.valueOf(this.type.toUpperCase()); - } - catch (IllegalArgumentException e) - { - getLog().error("Invalid value for configuration-option \"type\": " + this.type); - getLog().error("Valid values are: NONE, CREATE, DROP, BOTH"); - throw new MojoExecutionException("Invalid value for configuration-option \"type\""); - } - - - if (config.getProperty(DIALECT) == null) - throw new MojoFailureException("hibernate-dialect must be set!"); - - - if (target.equals(Target.SCRIPT) || target.equals(Target.NONE)) - { - project.getProperties().setProperty(EXPORT_SKIPPED_PROPERTY, "true"); - } - if ( - !modified - && !target.equals(Target.SCRIPT) - && !target.equals(Target.NONE) - && !force - ) - { - getLog().info("No modified annotated classes or mapping-files found and dialect unchanged."); - getLog().info("Skipping schema generation!"); - project.getProperties().setProperty(EXPORT_SKIPPED_PROPERTY, "true"); - return; - } - - - if ( config.getProperties().containsKey(NAMING_STRATEGY)) - { - String namingStrategy = config.getProperty(NAMING_STRATEGY); - getLog().debug("Explicitly set NamingStrategy: " + namingStrategy); - try - { - @SuppressWarnings("unchecked") - Class namingStrategyClass = (Class) Class.forName(namingStrategy); - config.setNamingStrategy(namingStrategyClass.newInstance()); - } - catch (Exception e) - { - getLog().error("Error setting NamingStrategy", e); - throw new MojoExecutionException(e.getMessage()); - } - } - - - Environment.verifyProperties(config.getProperties()); - ConfigurationHelper.resolvePlaceHolders(config.getProperties()); - registry = - (StandardServiceRegistryImpl) - new StandardServiceRegistryBuilder() - .applySettings(config.getProperties()) - .build(); - - config.buildMappings(); - - if (envers) - { - getLog().info("Automatic auditing via hibernate-envers enabled!"); - AuditConfiguration.getFor(config); - } - - SchemaExport export = new SchemaExport(registry, config); - export.setDelimiter(delimiter); - export.setFormat(format); - - File outF = new File(outputFile); - - if (!outF.isAbsolute()) - { - // Interpret relative file path relative to build directory - outF = new File(buildDirectory, outputFile); - getLog().info("Adjusted relative path, resulting path is " + outF.getPath()); - } - - // Ensure that directory path for specified file exists - File outFileParentDir = outF.getParentFile(); - if (null != outFileParentDir && !outFileParentDir.exists()) - { - try - { - getLog().info("Creating directory path for output file:" + outFileParentDir.getPath()); - outFileParentDir.mkdirs(); - } - catch (Exception e) - { - getLog().error("Error creating directory path for output file: " + e.getLocalizedMessage()); - } - } - - export.setOutputFile(outF.getPath()); - export.execute(target, type); - - for (Object exception : export.getExceptions()) - getLog().debug(exception.toString()); - } - finally - { - /** Stop Log-Capturing */ - MavenLogAppender.endPluginLog(this); - - /** Restore the old class-loader (TODO: is this really necessary?) */ - Thread.currentThread().setContextClassLoader(contextClassLoader); - - if (registry != null) - registry.destroy(); - } - - /** Write md5-sums for annotated classes to file */ - try - { - FileOutputStream fos = new FileOutputStream(saved); - ObjectOutputStream oos = new ObjectOutputStream(fos); - oos.writeObject(md5s); - oos.close(); - fos.close(); - } - catch (Exception e) - { - getLog().error("Cannot write md5-sums to file: " + e); - } - } - - 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! - * See: - * http://stackoverflow.com/questions/288828/how-to-use-a-jdbc-driver-fromodifiedm-an-arbitrary-location - */ - static final class DriverProxy implements Driver - { - private final Driver target; - - DriverProxy(Driver target) - { - if (target == null) - throw new NullPointerException(); - this.target = target; - } - - public java.sql.Driver getTarget() - { - return target; - } - - @Override - public boolean acceptsURL(String url) throws SQLException - { - return target.acceptsURL(url); - } - - @Override - public java.sql.Connection connect( - String url, - java.util.Properties info - ) - throws - SQLException - { - return target.connect(url, info); - } - - @Override - public int getMajorVersion() - { - return target.getMajorVersion(); - } - - @Override - public int getMinorVersion() - { - return target.getMinorVersion(); - } - - @Override - public DriverPropertyInfo[] getPropertyInfo( - String url, - Properties info - ) - throws - SQLException - { - return target.getPropertyInfo(url, info); - } - - @Override - public boolean jdbcCompliant() - { - return target.jdbcCompliant(); - } - - /** - * This Method cannot be annotated with @Override, becaus the plugin - * will not compile then under Java 1.6! - */ - public Logger getParentLogger() throws SQLFeatureNotSupportedException - { - throw new SQLFeatureNotSupportedException("Not supported, for backward-compatibility with Java 1.6"); - } - - @Override - public String toString() - { - return "Proxy: " + target; - } - - @Override - public int hashCode() - { - return target.hashCode(); - } - - @Override - public boolean equals(Object obj) - { - if (!(obj instanceof DriverProxy)) - return false; - DriverProxy other = (DriverProxy) obj; - return this.target.equals(other.target); - } - } -} diff --git a/src/main/java/de/juplo/plugins/hibernate4/ValidationConfiguration.java b/src/main/java/de/juplo/plugins/hibernate4/ValidationConfiguration.java deleted file mode 100644 index d16be201..00000000 --- a/src/main/java/de/juplo/plugins/hibernate4/ValidationConfiguration.java +++ /dev/null @@ -1,54 +0,0 @@ -package de.juplo.plugins.hibernate4; - -import javax.validation.Validation; - -import org.hibernate.cfg.Configuration; -import org.hibernate.cfg.beanvalidation.TypeSafeActivatorAccessor; -import org.hibernate.dialect.Dialect; -import org.hibernate.metamodel.source.MappingException; - - -/** - * This integration is usually performed by BeanValidationIntegrator. - * Unfortunately, that integration will only be activated upon - * initialization of the ServiceRegistry, which initializes - * DatasourceConnectionProviderImpl, which looks up the datasource, - * which requires a JNDI context ... - * We therefore reimplement the relevant parts of BeanValidatorIntegrator. - * Since that must occur after secondPassCompile(), which is invoked by - * Configuration.generateSchemaCreationScript, which is invoked by - * SchemaExport, some fancy subclassing is needed to invoke the integration - * at the right time. - * @author Mark Robinson - * @author Frank Schimmel - */ -public class ValidationConfiguration extends Configuration -{ - private static final long serialVersionUID = 1L; - - - @Override - protected void secondPassCompile() throws MappingException - { - super.secondPassCompile(); - - try - { - TypeSafeActivatorAccessor.applyRelationalConstraints( - Validation.buildDefaultValidatorFactory(), - classes.values(), - getProperties(), - ((Class)Class.forName(getProperty(Hbm2DdlMojo.DIALECT))).newInstance() - ); - } - catch (Exception e) - { - throw new RuntimeException(e); - } - } - - public String getTypeDefs() - { - return typeDefs.entrySet().toString(); - } -} diff --git a/src/main/java/org/hibernate/cfg/beanvalidation/TypeSafeActivatorAccessor.java b/src/main/java/org/hibernate/cfg/beanvalidation/TypeSafeActivatorAccessor.java deleted file mode 100644 index faece3f9..00000000 --- a/src/main/java/org/hibernate/cfg/beanvalidation/TypeSafeActivatorAccessor.java +++ /dev/null @@ -1,11 +0,0 @@ -package org.hibernate.cfg.beanvalidation; - -/** - * This class enables access to the public methods of {@link TypeSafeActivator} - * which itself is visible in the package only. - * - * @author Frank Schimmel - */ -public class TypeSafeActivatorAccessor extends TypeSafeActivator { - // Empty: just makes public methods accessible. -} diff --git a/src/main/resources/META-INF/m2e/lifecycle-mapping-metadata.xml b/src/main/resources/META-INF/m2e/lifecycle-mapping-metadata.xml deleted file mode 100644 index bd7af1e4..00000000 --- a/src/main/resources/META-INF/m2e/lifecycle-mapping-metadata.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - export - - - - - true - true - - - - - diff --git a/src/site/xhtml/configuration.xhtml b/src/site/xhtml/configuration.xhtml index 8360b8f8..e8c5afd5 100644 --- a/src/site/xhtml/configuration.xhtml +++ b/src/site/xhtml/configuration.xhtml @@ -19,7 +19,7 @@
 <plugin>
   <groupId>de.juplo</groupId>
-  <artifactId>hibernate4-maven-plugin</artifactId>
+  <artifactId>hibernate-maven-plugin</artifactId>
   <version>${project.version}</version>
   <executions>
     <execution>
@@ -46,7 +46,7 @@
   
 <plugin>
   <groupId>de.juplo</groupId>
-  <artifactId>hibernate4-maven-plugin</artifactId>
+  <artifactId>hibernate-maven-plugin</artifactId>
   <version>${project.version}</version>
   <executions>
     <execution>
@@ -109,7 +109,7 @@
 
   <plugin>
     <groupId>de.juplo</groupId>
-    <artifactId>hibernate4-maven-plugin</artifactId>
+    <artifactId>hibernate-maven-plugin</artifactId>
     <version>${project.version}</version>
     <executions>
       <execution>
@@ -130,8 +130,8 @@
   The relevant configuration-parameters are:
   

    -
  • driverClassName
  • -
  • hibernateDialect
  • +
  • driver
  • +
  • dialect
  • url
  • username
  • password
  • @@ -143,7 +143,7 @@
     <plugin>
       <groupId>de.juplo</groupId>
    -  <artifactId>hibernate4-maven-plugin</artifactId>
    +  <artifactId>hibernate-maven-plugin</artifactId>
       <version>${project.version}</version>
       <executions>
         <execution>
    @@ -153,8 +153,8 @@
         </execution>
       </executions>
       <configuration>
    -    <driverClassName>org.hsqldb.jdbcDriver</driverClassName>
    -    <hibernateDialect>org.hibernate.dialect.HSQLDialect</hibernateDialect>
    +    <driver>org.hsqldb.jdbcDriver</driver>
    +    <dialect>org.hibernate.dialect.HSQLDialect</dialect>
         <url><![CDATA[jdbc:hsqldb:target/db/fotos;shutdown=true]]></url>
         <username>sa</username>
         <password></password>
    @@ -182,7 +182,7 @@
       
       

    If you are in doubt about where a configuration-value comes from, run - maven with the debug-output enabled: mvn -X hibernate4:export + maven with the debug-output enabled: mvn -X hibernate:export and be aware, that maven-properties can be overwitten on the command-line, in your ~/.m2/settings.xml and in a profile.

    @@ -199,7 +199,7 @@
     <plugin>
       <groupId>de.juplo</groupId>
    -  <artifactId>hibernate4-maven-plugin</artifactId>
    +  <artifactId>hibernate-maven-plugin</artifactId>
       <version>${project.version}</version>
       <executions>
         <execution>
    diff --git a/src/site/xhtml/debugging.xhtml b/src/site/xhtml/debugging.xhtml
    index 8f91f3f9..c67d8c00 100644
    --- a/src/site/xhtml/debugging.xhtml
    +++ b/src/site/xhtml/debugging.xhtml
    @@ -5,7 +5,7 @@
      
      
       

    - If you are new to hibernate4-maven-plugin, in many cases, the + If you are new to hibernate-maven-plugin, in many cases, the {Configuration-Method-Precedence} may be the source of configuration errors. To solve this problem, you should run maven with the debugging output @@ -13,18 +13,18 @@ For example, by executing:

    -mvn -X compile hibernate4:export
    +mvn -X compile hibernate:export

    - (The compile might be necessary, because hibernate4-maven-plugin + (The compile might be necessary, because hibernate-maven-plugin has to scan the compiled classes for annotations!)

    - Unlike the majority of the maven-plugins, hibernate4-maven-plugin was + Unlike the majority of the maven-plugins, hibernate-maven-plugin was designed to give a good many hints, when debugging is enabled. Because, if you do not know, what went wrong, you can't fix it!

    - But be warned: hibernate4-maven-plugin tends to be very chatty ;) + But be warned: hibernate-maven-plugin tends to be very chatty ;)

    diff --git a/src/site/xhtml/force.xhtml b/src/site/xhtml/force.xhtml index 0a94070e..cd582db3 100644 --- a/src/site/xhtml/force.xhtml +++ b/src/site/xhtml/force.xhtml @@ -5,7 +5,7 @@

    - The hibernate4-maven-plugin computes MD5-sums for all found annotated + The hibernate-maven-plugin computes MD5-sums for all found annotated classes and stores them together with the generated schema. If no classes were changed or added and the dialect wasn't changed too, it automatically skips the configured schema-export, to speed up the development @@ -19,14 +19,14 @@ may fail, when the execution is skipped.

    - If you need the hibernate4-maven-plugin to <never skip execution automatically>, + If you need the hibernate-maven-plugin to <never skip execution automatically>, you can force it to do so, if you set the parameter force to true:

     <plugin>
       <groupId>de.juplo</groupId>
    -  <artifactId>hibernate4-maven-plugin</artifactId>
    +  <artifactId>hibernate-maven-plugin</artifactId>
       <version>${project.version}</version>
       <configuration>
         <force>true</force>
    @@ -34,7 +34,7 @@
     </plugin>

    Or you may specify -Dhibernate.export.force=true at the command line, - if you want to force hibernate4-maven-plugin only once. + if you want to force hibernate-maven-plugin only once.

    diff --git a/src/site/xhtml/index.xhtml b/src/site/xhtml/index.xhtml index 39d191ea..a30e6d62 100644 --- a/src/site/xhtml/index.xhtml +++ b/src/site/xhtml/index.xhtml @@ -7,7 +7,7 @@

    Hibernate 4 Maven Plugin

    A simple Plugin for generating a Database-Schema from Hibernate 4 Mapping-Annotations

    - The hibernate4-maven-plugin is a plugin for generating a database-schema + The hibernate-maven-plugin is a plugin for generating a database-schema from your Hibernate-4-Mappings and create or update your database accordingly. Its main usage is to automatically create and populate a test-database @@ -34,12 +34,12 @@

    Last but not least, in order to not slow down the development cycle, the - hibernate4-maven-plugin only executes the schema-export, if the mapping + hibernate-maven-plugin only executes the schema-export, if the mapping or the dialect changes (or if you force it to do so).

    For more information about the inspiration to write this tiny plugin, - read our blog-article about the hibernate4-maven-plugin. + read our blog-article about the hibernate-maven-plugin.

    Documentation

      @@ -48,7 +48,7 @@ and simple examples of how to use this plugin.
    • - See hibernate4:export and + See hibernate:export and Plugin Documentation for the full autogenerated documentation. These are mostly configuration-options of the Hibernate-Tools SchemaExport and SchemaUpdate, that do @@ -57,7 +57,7 @@

    Releases

      -
    • current version
    • +
    • current version
    • ${project.version} (this version)
    • 1.0.5
    • 1.0.4
    • diff --git a/src/site/xhtml/pitfalls.xhtml b/src/site/xhtml/pitfalls.xhtml index 71839293..3967811b 100644 --- a/src/site/xhtml/pitfalls.xhtml +++ b/src/site/xhtml/pitfalls.xhtml @@ -6,14 +6,14 @@

      Annotated classes in dependencies are not found.

      - hibernate4-maven-plugin by default scans dependencies in the scope + hibernate-maven-plugin by default scans dependencies in the scope compile. You can configure it to scan dependencies in other scopes as well. But it scans only direct dependencies. Transitive dependencies are not scanned for annotated classes. If some of your annotated classes are hidden in a transitive dependency, you can simply add that dependency explicitly.

      -

      hibernate4-maven-plugin always needs a database-connection

      +

      hibernate-maven-plugin always needs a database-connection

      The default-configuration uses the EXPORT-target of the SchemaExport-Tool. If you do not need to create a database with the evaluated schema, you can @@ -36,7 +36,7 @@ So a tidy maven-developer would usually scope it for runtime.

      - But this will break the execution of the hibernate4-maven-plugin. + But this will break the execution of the hibernate-maven-plugin. Since it will not be able to see the needed dependency, it will fail with an error-message like:

      @@ -70,7 +70,7 @@
       <plugin>
         <groupId>de.juplo</groupId>
      -  <artifactId>hibernate4-maven-plugin</artifactId>
      +  <artifactId>hibernate-maven-plugin</artifactId>
         <version>${project.version}</version>
         <executions>
           <execution>
      @@ -93,29 +93,29 @@
         Because otherwise, this dependency will unnecessarily bloat the
         runtime-dependencies of your project.
         

      -

      DBUnit fails after execution of hibernate4 was skipped because nothing has changed

      +

      DBUnit fails after execution of hibernate was skipped because nothing has changed

      - If hibernate4-maven-plugin skips its excecution, this may lead to errors in + If hibernate-maven-plugin skips its excecution, this may lead to errors in other plugins. For example, when importing sample-data in the automatically created database with the help of the dbunit-plugin, the CLEAN_INSERT-operation may fail because of foreign-key-constraints, - if the database was not recreated, because the hibernate4-maven-plugin has + if the database was not recreated, because the hibernate-maven-plugin has skipped its excecution.

      A quick fix to this problem is, to force - hibernate4-maven-plugin to export the schema every time it is running. + hibernate-maven-plugin to export the schema every time it is running. But to recreate the database on every testrun may noticeable slow down your development cycle, if you have to wait for slow IO.

      - To circumvent this problem, hibernate4-maven-plugin signals a skipped + To circumvent this problem, hibernate-maven-plugin signals a skipped excecution by setting the maven property $\{hibernate.export.skipped\} to true. You can configure other plugins to react on this signal. For example, the dbunit-plugin can be configured to skip its excecution, if - hibernate4-maven-plugin was skipped like this: + hibernate-maven-plugin was skipped like this:

       <plugin>
      @@ -128,7 +128,7 @@
         

      The database will not be recreated after a manual drop/clean

      If one manually drops the database or removes the hsqldb-files, it will not - be recreated by the hibernate4-maven-plugin, because it cannot detect, that + be recreated by the hibernate-maven-plugin, because it cannot detect, that the database needs to be recreated. This happens, because the plugin will not recreate the database if neither the configuration nor the annotated classes have changed, because an @@ -143,17 +143,17 @@ Otherwise the recreation must be forced:

      -mvn hibernate4:export -Dhibernate.export.force=true
      -

      The hibernate4:export goal is not executed, when tests are skipped

      +mvn hibernate:export -Dhibernate.export.force=true
      +

      The hibernate:export goal is not executed, when tests are skipped

      - The hibernate4-maven-plugin automatically skips its execution, when + The hibernate-maven-plugin automatically skips its execution, when maven.test.skip is set to true. If you need it to be always executed, you can configure that explicitly like this:

       <plugin>
         <groupId>de.juplo</groupId>
      -  <artifactId>hibernate4-maven-plugin</artifactId>
      +  <artifactId>hibernate-maven-plugin</artifactId>
         ...
         <configuration>
           <skip>false</skip>
      @@ -173,7 +173,7 @@ mvn hibernate4:export -Dhibernate.export.force=true
       <plugin>
         <groupId>de.juplo</groupId>
      -  <artifactId>hibernate4-maven-plugin</artifactId>
      +  <artifactId>hibernate-maven-plugin</artifactId>
         ...
         <configuration>
           <scanDependencies>none</scanDependencies>
      diff --git a/src/site/xhtml/skip.xhtml b/src/site/xhtml/skip.xhtml
      index 51a20af7..5f893b82 100644
      --- a/src/site/xhtml/skip.xhtml
      +++ b/src/site/xhtml/skip.xhtml
      @@ -5,7 +5,7 @@
        
        
         

      - In most use-cases, the hibernate4-maven-plugin is used to create a + In most use-cases, the hibernate-maven-plugin is used to create a test-database automatically. In this use-cases, it is very likely, that it will result in mistakes/errors, if the goal is executed, when the tests are skipped. @@ -19,7 +19,7 @@

      Because of this, the configuration-parameter skip defaults to the value of the proptery maven.test.skip. This way, the execution of the - hibernate4-maven-plugin is skipped automatically, when the tests are + hibernate-maven-plugin is skipped automatically, when the tests are skipped. Think of it as a build-in security-belt.

      @@ -30,7 +30,7 @@

       <plugin>
         <groupId>de.juplo</groupId>
      -  <artifactId>hibernate4-maven-plugin</artifactId>
      +  <artifactId>hibernate-maven-plugin</artifactId>
         ...
         <configuration>
           <skip>false</skip>
      @@ -44,7 +44,7 @@
         
       <plugin>
         <groupId>de.juplo</groupId>
      -  <artifactId>hibernate4-maven-plugin</artifactId>
      +  <artifactId>hibernate-maven-plugin</artifactId>
         ...
         <configuration>
           <skip>${foo.bar}</skip>