WIP
[hibernate4-maven-plugin] / src / main / java / de / juplo / plugins / hibernate / AbstractSchemaMojo.java
index 6f224b0..71e1250 100644 (file)
@@ -10,9 +10,8 @@ import java.io.InputStream;
 import java.net.MalformedURLException;
 import java.net.URL;
 import java.security.NoSuchAlgorithmException;
+import java.time.ZonedDateTime;
 import java.util.Collections;
-import java.util.EnumSet;
-import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.LinkedHashSet;
@@ -48,7 +47,6 @@ import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
 import org.hibernate.boot.registry.classloading.spi.ClassLoadingException;
 import org.hibernate.boot.registry.selector.spi.StrategySelector;
 import org.hibernate.boot.spi.MetadataImplementor;
-import org.hibernate.cfg.AvailableSettings;
 import static org.hibernate.cfg.AvailableSettings.DIALECT;
 import static org.hibernate.cfg.AvailableSettings.DRIVER;
 import static org.hibernate.cfg.AvailableSettings.FORMAT_SQL;
@@ -64,18 +62,11 @@ import static org.hibernate.cfg.AvailableSettings.PHYSICAL_NAMING_STRATEGY;
 import static org.hibernate.cfg.AvailableSettings.SHOW_SQL;
 import static org.hibernate.cfg.AvailableSettings.USER;
 import static org.hibernate.cfg.AvailableSettings.URL;
-import org.hibernate.engine.config.spi.ConfigurationService;
 import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider;
 import org.hibernate.internal.util.config.ConfigurationException;
 import org.hibernate.jpa.boot.internal.ParsedPersistenceXmlDescriptor;
 import org.hibernate.jpa.boot.internal.PersistenceXmlParser;
-import org.hibernate.tool.schema.TargetType;
 import org.hibernate.tool.schema.internal.ExceptionHandlerCollectingImpl;
-import org.hibernate.tool.schema.internal.exec.ScriptTargetOutputToFile;
-import org.hibernate.tool.schema.spi.ExecutionOptions;
-import org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator;
-import org.hibernate.tool.schema.spi.ScriptTargetOutput;
-import org.hibernate.tool.schema.spi.TargetDescriptor;
 import org.scannotation.AnnotationDB;
 
 
@@ -95,6 +86,7 @@ public abstract class AbstractSchemaMojo extends AbstractMojo
   public final static String SCAN_TESTCLASSES = "hibernate.schema.scan.test_classes";
   public final static String TEST_OUTPUTDIRECTORY = "project.build.testOutputDirectory";
   public final static String SKIPPED = "hibernate.schema.skipped";
+  public final static String SCRIPT = "hibernate.schema.script";
 
   private final static Pattern SPLIT = Pattern.compile("[^,\\s]+");
 
@@ -504,6 +496,8 @@ public abstract class AbstractSchemaMojo extends AbstractMojo
 
       /** Check, that the outputfile is writable */
       final File output = getOutputFile(filename);
+      /** Check, if the outputfile is missing or was changed */
+      checkOutputFile(output, tracker);
 
       /** Configure Hibernate */
       final StandardServiceRegistry serviceRegistry =
@@ -682,42 +676,6 @@ public abstract class AbstractSchemaMojo extends AbstractMojo
             );
       }
 
-      /** Prepare the generation of the SQL */
-      Map settings = new HashMap();
-      settings.putAll(
-          serviceRegistry
-              .getService(ConfigurationService.class)
-              .getSettings()
-              );
-      ExceptionHandlerCollectingImpl handler =
-          new ExceptionHandlerCollectingImpl();
-      ExecutionOptions options =
-          SchemaManagementToolCoordinator
-              .buildExecutionOptions(settings, handler);
-      final EnumSet<TargetType> targetTypes = EnumSet.of(TargetType.SCRIPT);
-      if (execute)
-        targetTypes.add(TargetType.DATABASE);
-      TargetDescriptor target = new TargetDescriptor()
-      {
-        @Override
-        public EnumSet<TargetType> getTargetTypes()
-        {
-          return targetTypes;
-        }
-
-        @Override
-        public ScriptTargetOutput getScriptTargetOutput()
-        {
-          String charset =
-              (String)
-              serviceRegistry
-                  .getService(ConfigurationService.class)
-                  .getSettings()
-                  .get(AvailableSettings.HBM2DDL_CHARSET_NAME);
-          return new ScriptTargetOutputToFile(output, charset);
-        }
-      };
-
       /**
        * Change class-loader of current thread.
        * This is necessary, because still not all parts of Hibernate 5 use
@@ -728,13 +686,27 @@ public abstract class AbstractSchemaMojo extends AbstractMojo
       try
       {
         thread.setContextClassLoader(classLoader);
-        build((MetadataImplementor)metadataBuilder.build(), options, target);
+        ExceptionHandlerCollectingImpl handler =
+            build((MetadataImplementor)metadataBuilder.build(), output);
+        if (handler.getExceptions().size() > 0)
+        {
+          StringBuilder builder = new StringBuilder();
+          builder.append("Hibernate failed:");
+          for (Exception e : handler.getExceptions())
+          {
+            builder.append("\n * ");
+            builder.append(e.getMessage());
+          }
+          String error = builder.toString();
+          getLog().error(error);
+          throw new MojoFailureException(error);
+        }
       }
       finally
       {
         thread.setContextClassLoader(contextClassLoader);
-        for (Exception e : handler.getExceptions())
-          getLog().error(e.getMessage());
+        /** Track, the content of the generated script */
+        checkOutputFile(output, tracker);
       }
     }
     catch (MojoExecutionException e)
@@ -766,10 +738,9 @@ public abstract class AbstractSchemaMojo extends AbstractMojo
   }
 
 
-  abstract void build(
+  abstract ExceptionHandlerCollectingImpl build(
       MetadataImplementor metadata,
-      ExecutionOptions options,
-      TargetDescriptor target
+      File file
       )
     throws
       MojoFailureException,
@@ -919,7 +890,14 @@ public abstract class AbstractSchemaMojo extends AbstractMojo
      * switched to "true", the genearation fo the schema should be forced!
      */
     if (tracker.check(EXECUTE, execute.toString()) && execute)
+    {
+      getLog().info(
+          "hibernate.schema.execute was switched on: " +
+          "forcing generation/execution of SQL"
+          );
       tracker.touch();
+    }
+    configure(properties, execute, EXECUTE);
 
     /**
      * Configure the generation of the SQL.
@@ -932,10 +910,10 @@ public abstract class AbstractSchemaMojo extends AbstractMojo
     configure(properties, createNamespaces, HBM2DLL_CREATE_NAMESPACES);
     configure(properties, implicitNamingStrategy, IMPLICIT_NAMING_STRATEGY);
     configure(properties, physicalNamingStrategy, PHYSICAL_NAMING_STRATEGY);
-    tracker.track(OUTPUTDIRECTORY, outputDirectory); // << not reflected in hibernate configuration!
-    tracker.track(SCAN_DEPENDENCIES, scanDependencies); // << not reflected in hibernate configuration!
-    tracker.track(SCAN_TESTCLASSES, scanTestClasses.toString()); // << not reflected in hibernate configuration!
-    tracker.track(TEST_OUTPUTDIRECTORY, testOutputDirectory); // << not reflected in hibernate configuration!
+    configure(properties, outputDirectory, OUTPUTDIRECTORY);
+    configure(properties, scanDependencies, SCAN_DEPENDENCIES);
+    configure(properties, scanTestClasses, SCAN_TESTCLASSES);
+    configure(properties, testOutputDirectory, TEST_OUTPUTDIRECTORY);
 
     /**
      * Special treatment for the configuration-value "show": a change of its
@@ -962,7 +940,7 @@ public abstract class AbstractSchemaMojo extends AbstractMojo
       throw new MojoFailureException("Hibernate configuration is missing!");
     }
 
-    getLog().info("Gathered hibernate-configuration (turn on debugging for details):");
+    getLog().info("Gathered configuration:");
     for (Entry<Object,Object> entry : properties.entrySet())
       getLog().info("  " + entry.getKey() + " = " + entry.getValue());
   }
@@ -1006,14 +984,22 @@ public abstract class AbstractSchemaMojo extends AbstractMojo
     if (value != null)
     {
       if (properties.containsKey(key))
-        getLog().info(
-            "Overwriting property " + key + "=\"" +
-            properties.getProperty(key) +
-            "\" with value \"" + value + "\""
-            );
+      {
+        if (!properties.getProperty(key).equals(value))
+        {
+          getLog().info(
+              "Overwriting property " + key + "=\"" +
+              properties.getProperty(key) +
+              "\" with value \"" + value + "\""
+              );
+          properties.setProperty(key, value);
+        }
+      }
       else
+      {
         getLog().debug("Using value \"" + value + "\" for property " + key);
-      properties.setProperty(key, value);
+        properties.setProperty(key, value);
+      }
     }
   }
 
@@ -1078,6 +1064,26 @@ public abstract class AbstractSchemaMojo extends AbstractMojo
     return output;
   }
 
+  private void checkOutputFile(File output, ModificationTracker tracker)
+      throws
+        MojoExecutionException
+  {
+    try
+    {
+      if (output.exists())
+        tracker.track(SCRIPT, new FileInputStream(output));
+      else
+        tracker.track(SCRIPT, ZonedDateTime.now().toString());
+    }
+    catch (IOException e)
+    {
+      String error =
+          "Error while checking the generated script: " + e.getMessage();
+      getLog().error(error);
+      throw new MojoExecutionException(error);
+    }
+  }
+
   private void addMappings(MetadataSources sources, ModificationTracker tracker)
       throws MojoFailureException
   {