X-Git-Url: https://juplo.de/gitweb/?p=website;a=blobdiff_plain;f=dist%2Fhibernate-maven-plugin-2.1.0%2Fxref%2Fde%2Fjuplo%2Fplugins%2Fhibernate%2FAbstractSchemaMojo.html;fp=dist%2Fhibernate-maven-plugin-2.1.0%2Fxref%2Fde%2Fjuplo%2Fplugins%2Fhibernate%2FAbstractSchemaMojo.html;h=0000000000000000000000000000000000000000;hp=8522d9a69900b9de3fcaffb2e67ad95f4f673913;hb=b293b312d6f0dd8b2dc716375fd442dd295a9942;hpb=9179a67d9952d3b63e95686dbd6cacd3c9e13cb2 diff --git a/dist/hibernate-maven-plugin-2.1.0/xref/de/juplo/plugins/hibernate/AbstractSchemaMojo.html b/dist/hibernate-maven-plugin-2.1.0/xref/de/juplo/plugins/hibernate/AbstractSchemaMojo.html deleted file mode 100644 index 8522d9a6..00000000 --- a/dist/hibernate-maven-plugin-2.1.0/xref/de/juplo/plugins/hibernate/AbstractSchemaMojo.html +++ /dev/null @@ -1,1433 +0,0 @@ - - -
--1 package de.juplo.plugins.hibernate; -2 -3 -4 import com.pyx4j.log4j.MavenLogAppender; -5 import java.io.File; -6 import java.io.FileInputStream; -7 import java.io.FileOutputStream; -8 import java.io.IOException; -9 import java.io.InputStream; -10 import java.net.MalformedURLException; -11 import java.net.URL; -12 import java.security.NoSuchAlgorithmException; -13 import java.time.ZonedDateTime; -14 import java.util.Collections; -15 import java.util.EnumSet; -16 import java.util.HashMap; -17 import java.util.HashSet; -18 import java.util.Iterator; -19 import java.util.LinkedHashSet; -20 import java.util.List; -21 import java.util.Map; -22 import java.util.Map.Entry; -23 import java.util.Properties; -24 import java.util.Set; -25 import java.util.regex.Matcher; -26 import java.util.regex.Pattern; -27 import javax.persistence.Embeddable; -28 import javax.persistence.Entity; -29 import javax.persistence.MappedSuperclass; -30 import javax.persistence.spi.PersistenceUnitTransactionType; -31 import org.apache.maven.artifact.Artifact; -32 import org.apache.maven.model.Resource; -33 import org.apache.maven.plugin.AbstractMojo; -34 import org.apache.maven.plugin.MojoExecutionException; -35 import org.apache.maven.plugin.MojoFailureException; -36 import org.apache.maven.project.MavenProject; -37 import org.hibernate.boot.MetadataBuilder; -38 import org.hibernate.boot.MetadataSources; -39 import org.hibernate.boot.cfgxml.internal.ConfigLoader; -40 import org.hibernate.boot.cfgxml.spi.LoadedConfig; -41 import org.hibernate.boot.cfgxml.spi.MappingReference; -42 import org.hibernate.boot.model.naming.ImplicitNamingStrategy; -43 import org.hibernate.boot.model.naming.PhysicalNamingStrategy; -44 import org.hibernate.boot.registry.BootstrapServiceRegistry; -45 import org.hibernate.boot.registry.BootstrapServiceRegistryBuilder; -46 import org.hibernate.boot.registry.StandardServiceRegistry; -47 import org.hibernate.boot.registry.StandardServiceRegistryBuilder; -48 import org.hibernate.boot.registry.classloading.spi.ClassLoaderService; -49 import org.hibernate.boot.registry.classloading.spi.ClassLoadingException; -50 import org.hibernate.boot.registry.selector.spi.StrategySelector; -51 import org.hibernate.boot.spi.MetadataImplementor; -52 import org.hibernate.cfg.AvailableSettings; -53 import static org.hibernate.cfg.AvailableSettings.DIALECT; -54 import static org.hibernate.cfg.AvailableSettings.DRIVER; -55 import static org.hibernate.cfg.AvailableSettings.FORMAT_SQL; -56 import static org.hibernate.cfg.AvailableSettings.HBM2DDL_DELIMITER; -57 import static org.hibernate.cfg.AvailableSettings.HBM2DLL_CREATE_NAMESPACES; -58 import static org.hibernate.cfg.AvailableSettings.IMPLICIT_NAMING_STRATEGY; -59 import static org.hibernate.cfg.AvailableSettings.JPA_JDBC_DRIVER; -60 import static org.hibernate.cfg.AvailableSettings.JPA_JDBC_PASSWORD; -61 import static org.hibernate.cfg.AvailableSettings.JPA_JDBC_URL; -62 import static org.hibernate.cfg.AvailableSettings.JPA_JDBC_USER; -63 import static org.hibernate.cfg.AvailableSettings.PASS; -64 import static org.hibernate.cfg.AvailableSettings.PHYSICAL_NAMING_STRATEGY; -65 import static org.hibernate.cfg.AvailableSettings.SHOW_SQL; -66 import static org.hibernate.cfg.AvailableSettings.USER; -67 import static org.hibernate.cfg.AvailableSettings.URL; -68 import org.hibernate.engine.config.spi.ConfigurationService; -69 import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider; -70 import org.hibernate.internal.util.config.ConfigurationException; -71 import org.hibernate.jpa.boot.internal.ParsedPersistenceXmlDescriptor; -72 import org.hibernate.jpa.boot.internal.PersistenceXmlParser; -73 import org.hibernate.tool.schema.TargetType; -74 import org.hibernate.tool.schema.internal.ExceptionHandlerCollectingImpl; -75 import org.hibernate.tool.schema.internal.exec.ScriptTargetOutputToFile; -76 import org.hibernate.tool.schema.spi.ExecutionOptions; -77 import org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator; -78 import org.hibernate.tool.schema.spi.ScriptTargetOutput; -79 import org.hibernate.tool.schema.spi.TargetDescriptor; -80 import org.scannotation.AnnotationDB; -81 -82 -83 /** -84 * Baseclass with common attributes and methods. -85 * -86 * @phase process-classes -87 * @threadSafe -88 * @requiresDependencyResolution runtime -89 */ -90 public abstract class AbstractSchemaMojo extends AbstractMojo -91 { -92 public final static String EXECUTE = "hibernate.schema.execute"; -93 public final static String OUTPUTDIRECTORY = "project.build.outputDirectory"; -94 public final static String SCAN_CLASSES = "hibernate.schema.scan.classes"; -95 public final static String SCAN_DEPENDENCIES = "hibernate.schema.scan.dependencies"; -96 public final static String SCAN_TESTCLASSES = "hibernate.schema.scan.test_classes"; -97 public final static String TEST_OUTPUTDIRECTORY = "project.build.testOutputDirectory"; -98 public final static String SKIPPED = "hibernate.schema.skipped"; -99 public final static String SCRIPT = "hibernate.schema.script"; -100 -101 private final static Pattern SPLIT = Pattern.compile("[^,\\s]+"); -102 -103 private final Set<String> packages = new HashSet<String>(); -104 -105 -106 /** -107 * The maven project. -108 * <p> -109 * Only needed internally. -110 * -111 * @parameter property="project" -112 * @required -113 * @readonly -114 */ -115 private MavenProject project; -116 -117 /** -118 * Build-directory. -119 * <p> -120 * Only needed internally. -121 * -122 * @parameter property="project.build.directory" -123 * @required -124 * @readonly -125 */ -126 private String buildDirectory; -127 -128 -129 /** Parameters to configure the genaration of the SQL *********************/ -130 -131 /** -132 * Excecute the generated SQL. -133 * If set to <code>false</code>, only the SQL-script is created and the -134 * database is not touched. -135 * <p> -136 * <strong>Important:</strong> -137 * This configuration value can only be configured through the -138 * <code>pom.xml</code>, or by the definition of a system-property, because -139 * it is not known by Hibernate nor JPA and, hence, not picked up from -140 * their configuration! -141 * -142 * @parameter property="hibernate.schema.execute" default-value="true" -143 * @since 2.0 -144 */ -145 private Boolean execute; -146 -147 /** -148 * Skip execution -149 * <p> -150 * If set to <code>true</code>, the execution is skipped. -151 * <p> -152 * A skipped execution is signaled via the maven-property -153 * <code>${hibernate.schema.skipped}</code>. -154 * <p> -155 * The execution is skipped automatically, if no modified or newly added -156 * annotated classes are found and the dialect was not changed. -157 * <p> -158 * <strong>Important:</strong> -159 * This configuration value can only be configured through the -160 * <code>pom.xml</code>, or by the definition of a system-property, because -161 * it is not known by Hibernate nor JPA and, hence, not picked up from -162 * their configuration! -163 * -164 * @parameter property="hibernate.schema.skip" default-value="${maven.test.skip}" -165 * @since 1.0 -166 */ -167 private boolean skip; -168 -169 /** -170 * Force generation/execution -171 * <p> -172 * Force the generation and (if configured) the execution of the SQL, even if -173 * no modified or newly added annotated classes where found and the -174 * configuration was not changed. -175 * <p> -176 * <code>skip</code> takes precedence over <code>force</code>. -177 * <p> -178 * <strong>Important:</strong> -179 * This configuration value can only be configured through the -180 * <code>pom.xml</code>, or by the definition of a system-property, because -181 * it is not known by Hibernate nor JPA and, hence, not picked up from -182 * their configuration! -183 * -184 * @parameter property="hibernate.schema.force" default-value="false" -185 * @since 1.0 -186 */ -187 private boolean force; -188 -189 /** -190 * Hibernate dialect. -191 * -192 * @parameter property="hibernate.dialect" -193 * @since 1.0 -194 */ -195 private String dialect; -196 -197 /** -198 * Delimiter in output-file. -199 * <p> -200 * <strong>Important:</strong> -201 * This configuration value can only be configured through the -202 * <code>pom.xml</code>, or by the definition of a system-property, because -203 * it is not known by Hibernate nor JPA and, hence, not picked up from -204 * their configuration! -205 * -206 * @parameter property="hibernate.hbm2ddl.delimiter" default-value=";" -207 * @since 1.0 -208 */ -209 private String delimiter; -210 -211 /** -212 * Show the generated SQL in the command-line output. -213 * -214 * @parameter property="hibernate.show_sql" -215 * @since 1.0 -216 */ -217 private Boolean show; -218 -219 /** -220 * Format output-file. -221 * -222 * @parameter property="hibernate.format_sql" -223 * @since 1.0 -224 */ -225 private Boolean format; -226 -227 /** -228 * Specifies whether to automatically create also the database schema/catalog. -229 * -230 * @parameter property="hibernate.hbm2dll.create_namespaces" default-value="false" -231 * @since 2.0 -232 */ -233 private Boolean createNamespaces; -234 -235 /** -236 * Implicit naming strategy -237 * -238 * @parameter property="hibernate.implicit_naming_strategy" -239 * @since 2.0 -240 */ -241 private String implicitNamingStrategy; -242 -243 /** -244 * Physical naming strategy -245 * -246 * @parameter property="hibernate.physical_naming_strategy" -247 * @since 2.0 -248 */ -249 private String physicalNamingStrategy; -250 -251 /** -252 * Wether the project should be scanned for annotated-classes, or not -253 * <p> -254 * This parameter is intended to allow overwriting of the parameter -255 * <code>exclude-unlisted-classes</code> of a <code>persistence-unit</code>. -256 * If not specified, it defaults to <code>true</code> -257 * -258 * @parameter property="hibernate.schema.scan.classes" -259 * @since 2.0 -260 */ -261 private Boolean scanClasses; -262 -263 /** -264 * Classes-Directory to scan. -265 * <p> -266 * This parameter defaults to the maven build-output-directory for classes. -267 * Additionally, all dependencies are scanned for annotated classes. -268 * <p> -269 * <strong>Important:</strong> -270 * This configuration value can only be configured through the -271 * <code>pom.xml</code>, or by the definition of a system-property, because -272 * it is not known by Hibernate nor JPA and, hence, not picked up from -273 * their configuration! -274 * -275 * @parameter property="project.build.outputDirectory" -276 * @since 1.0 -277 */ -278 private String outputDirectory; -279 -280 /** -281 * Dependency-Scopes, that should be scanned for annotated classes. -282 * <p> -283 * By default, only dependencies in the scope <code>compile</code> are -284 * scanned for annotated classes. Multiple scopes can be seperated by -285 * white space or commas. -286 * <p> -287 * If you do not want any dependencies to be scanned for annotated -288 * classes, set this parameter to <code>none</code>. -289 * <p> -290 * The plugin does not scan for annotated classes in transitive -291 * dependencies. If some of your annotated classes are hidden in a -292 * transitive dependency, you can simply add that dependency explicitly. -293 * -294 * @parameter property="hibernate.schema.scan.dependencies" default-value="compile" -295 * @since 1.0.3 -296 */ -297 private String scanDependencies; -298 -299 /** -300 * Whether to scan the test-branch of the project for annotated classes, or -301 * not. -302 * <p> -303 * If this parameter is set to <code>true</code> the test-classes of the -304 * artifact will be scanned for hibernate-annotated classes additionally. -305 * <p> -306 * <strong>Important:</strong> -307 * This configuration value can only be configured through the -308 * <code>pom.xml</code>, or by the definition of a system-property, because -309 * it is not known by Hibernate nor JPA and, hence, not picked up from -310 * their configuration! -311 * -312 * @parameter property="hibernate.schema.scan.test_classes" default-value="false" -313 * @since 1.0.1 -314 */ -315 private Boolean scanTestClasses; -316 -317 /** -318 * Test-Classes-Directory to scan. -319 * <p> -320 * This parameter defaults to the maven build-output-directory for -321 * test-classes. -322 * <p> -323 * This parameter is only used, when <code>scanTestClasses</code> is set -324 * to <code>true</code>! -325 * <p> -326 * <strong>Important:</strong> -327 * This configuration value can only be configured through the -328 * <code>pom.xml</code>, or by the definition of a system-property, because -329 * it is not known by Hibernate nor JPA and, hence, not picked up from -330 * their configuration! -331 * -332 * @parameter property="project.build.testOutputDirectory" -333 * @since 1.0.2 -334 */ -335 private String testOutputDirectory; -336 -337 -338 /** Conection parameters *************************************************/ -339 -340 /** -341 * SQL-Driver name. -342 * -343 * @parameter property="hibernate.connection.driver_class" -344 * @since 1.0 -345 */ -346 private String driver; -347 -348 /** -349 * Database URL. -350 * -351 * @parameter property="hibernate.connection.url" -352 * @since 1.0 -353 */ -354 private String url; -355 -356 /** -357 * Database username -358 * -359 * @parameter property="hibernate.connection.username" -360 * @since 1.0 -361 */ -362 private String username; -363 -364 /** -365 * Database password -366 * -367 * @parameter property="hibernate.connection.password" -368 * @since 1.0 -369 */ -370 private String password; -371 -372 -373 /** Parameters to locate configuration sources ****************************/ -374 -375 /** -376 * Path to a file or name of a ressource with hibernate properties. -377 * If this parameter is specified, the plugin will try to load configuration -378 * values from a file with the given path or a ressource on the classpath with -379 * the given name. If both fails, the execution of the plugin will fail. -380 * <p> -381 * If this parameter is not set the plugin will load configuration values -382 * from a ressource named <code>hibernate.properties</code> on the classpath, -383 * if it is present, but will not fail if there is no such ressource. -384 * <p> -385 * During ressource-lookup, the test-classpath takes precedence. -386 * -387 * @parameter -388 * @since 1.0 -389 */ -390 private String hibernateProperties; -391 -392 /** -393 * Path to Hibernate configuration file (.cfg.xml). -394 * If this parameter is specified, the plugin will try to load configuration -395 * values from a file with the given path or a ressource on the classpath with -396 * the given name. If both fails, the execution of the plugin will fail. -397 * <p> -398 * If this parameter is not set the plugin will load configuration values -399 * from a ressource named <code>hibernate.cfg.xml</code> on the classpath, -400 * if it is present, but will not fail if there is no such ressource. -401 * <p> -402 * During ressource-lookup, the test-classpath takes precedence. -403 * <p> -404 * Settings in this file will overwrite settings in the properties file. -405 * -406 * @parameter -407 * @since 1.1.0 -408 */ -409 private String hibernateConfig; -410 -411 /** -412 * Name of the persistence-unit. -413 * If this parameter is specified, the plugin will try to load configuration -414 * values from a persistence-unit with the specified name. If no such -415 * persistence-unit can be found, the plugin will throw an exception. -416 * <p> -417 * If this parameter is not set and there is only one persistence-unit -418 * available, that unit will be used automatically. But if this parameter is -419 * not set and there are multiple persistence-units available on, -420 * the class-path, the execution of the plugin will fail. -421 * <p> -422 * Settings in this file will overwrite settings in the properties or the -423 * configuration file. -424 * -425 * @parameter -426 * @since 1.1.0 -427 */ -428 private String persistenceUnit; -429 -430 /** -431 * List of Hibernate-Mapping-Files (XML). -432 * Multiple files can be separated with white-spaces and/or commas. -433 * -434 * @parameter property="hibernate.mapping" -435 * @since 1.0.2 -436 */ -437 private String mappings; -438 -439 -440 -441 public final void execute(String filename) -442 throws -443 MojoFailureException, -444 MojoExecutionException -445 { -446 if (skip) -447 { -448 getLog().info("Execution of hibernate-maven-plugin was skipped!"); -449 project.getProperties().setProperty(SKIPPED, "true"); -450 return; -451 } -452 -453 ModificationTracker tracker; -454 try -455 { -456 tracker = new ModificationTracker(buildDirectory, filename, getLog()); -457 } -458 catch (NoSuchAlgorithmException e) -459 { -460 throw new MojoFailureException("Digest-Algorithm MD5 is missing!", e); -461 } -462 -463 final SimpleConnectionProvider connectionProvider = -464 new SimpleConnectionProvider(getLog()); -465 -466 try -467 { -468 /** Start extended logging */ -469 MavenLogAppender.startPluginLog(this); -470 -471 /** Load checksums for old mapping and configuration */ -472 tracker.load(); -473 -474 /** Create the ClassLoader */ -475 MutableClassLoader classLoader = createClassLoader(); -476 -477 /** Create a BootstrapServiceRegistry with the created ClassLoader */ -478 BootstrapServiceRegistry bootstrapServiceRegitry = -479 new BootstrapServiceRegistryBuilder() -480 .applyClassLoader(classLoader) -481 .build(); -482 ClassLoaderService classLoaderService = -483 bootstrapServiceRegitry.getService(ClassLoaderService.class); -484 -485 Properties properties = new Properties(); -486 ConfigLoader configLoader = new ConfigLoader(bootstrapServiceRegitry); -487 -488 /** Loading and merging configuration */ -489 properties.putAll(loadProperties(configLoader)); -490 LoadedConfig config = loadConfig(configLoader); -491 if (config != null) -492 properties.putAll(config.getConfigurationValues()); -493 ParsedPersistenceXmlDescriptor unit = -494 loadPersistenceUnit(classLoaderService, properties); -495 if (unit != null) -496 properties.putAll(unit.getProperties()); -497 -498 /** Overwriting/Completing configuration */ -499 configure(properties, tracker); -500 -501 /** Check configuration for modifications */ -502 if(tracker.track(properties)) -503 getLog().debug("Configuration has changed."); -504 else -505 getLog().debug("Configuration unchanged."); -506 -507 /** Check, that the outputfile is writable */ -508 final File output = getOutputFile(filename); -509 /** Check, if the outputfile is missing or was changed */ -510 checkOutputFile(output, tracker); -511 -512 /** Configure Hibernate */ -513 final StandardServiceRegistry serviceRegistry = -514 new StandardServiceRegistryBuilder(bootstrapServiceRegitry) -515 .applySettings(properties) -516 .addService(ConnectionProvider.class, connectionProvider) -517 .build(); -518 final MetadataSources sources = new MetadataSources(serviceRegistry); -519 -520 /** Add the remaining class-path-elements */ -521 completeClassPath(classLoader); -522 -523 /** Apply mappings from hibernate-configuration, if present */ -524 if (config != null) -525 { -526 for (MappingReference mapping : config.getMappingReferences()) -527 mapping.apply(sources); -528 } -529 -530 Set<String> classes; -531 if (unit == null) -532 { -533 /** No persistent unit: default behaviour */ -534 if (scanClasses == null) -535 scanClasses = true; -536 Set<URL> urls = new HashSet<URL>(); -537 if (scanClasses) -538 addRoot(urls, outputDirectory); -539 if (scanTestClasses) -540 addRoot(urls, testOutputDirectory); -541 addDependencies(urls); -542 classes = scanUrls(urls); -543 } -544 else -545 { -546 /** Follow configuration in persisten unit */ -547 if (scanClasses == null) -548 scanClasses = !unit.isExcludeUnlistedClasses(); -549 Set<URL> urls = new HashSet<URL>(); -550 if (scanClasses) -551 { -552 /** -553 * Scan the root of the persiten unit and configured jars for -554 * annotated classes -555 */ -556 urls.add(unit.getPersistenceUnitRootUrl()); -557 for (URL url : unit.getJarFileUrls()) -558 urls.add(url); -559 } -560 if (scanTestClasses) -561 addRoot(urls, testOutputDirectory); -562 classes = scanUrls(urls); -563 for (String className : unit.getManagedClassNames()) -564 classes.add(className); -565 /** -566 * Add mappings from the default mapping-file -567 * <code>META-INF/orm.xml</code>, if present -568 */ -569 boolean error = false; -570 InputStream is; -571 is = classLoader.getResourceAsStream("META-INF/orm.xml"); -572 if (is != null) -573 { -574 getLog().info("Adding default JPA-XML-mapping from META-INF/orm.xml"); -575 try -576 { -577 tracker.track("META-INF/orm.xml", is); -578 sources.addResource("META-INF/orm.xml"); -579 } -580 catch (IOException e) -581 { -582 getLog().error("cannot read META-INF/orm.xml: " + e); -583 error = true; -584 } -585 } -586 else -587 { -588 getLog().debug("no META-INF/orm.xml found"); -589 } -590 /** -591 * Add mappings from files, that are explicitly configured in the -592 * persistence unit -593 */ -594 for (String mapping : unit.getMappingFileNames()) -595 { -596 getLog().info("Adding explicitly configured mapping from " + mapping); -597 is = classLoader.getResourceAsStream(mapping); -598 if (is != null) -599 { -600 try -601 { -602 tracker.track(mapping, is); -603 sources.addResource(mapping); -604 } -605 catch (IOException e) -606 { -607 getLog().info("cannot read mapping-file " + mapping + ": " + e); -608 error = true; -609 } -610 } -611 else -612 { -613 getLog().error("cannot find mapping-file " + mapping); -614 error = true; -615 } -616 } -617 if (error) -618 throw new MojoFailureException( -619 "error, while reading mappings configured in persistence-unit \"" + -620 unit.getName() + -621 "\"" -622 ); -623 } -624 -625 /** Add the configured/collected annotated classes */ -626 for (String className : classes) -627 addAnnotated(className, sources, classLoaderService, tracker); -628 -629 /** Add explicitly configured classes */ -630 addMappings(sources, tracker); -631 -632 /** Skip execution, if mapping and configuration is unchanged */ -633 if (!tracker.modified()) -634 { -635 getLog().info("Mapping and configuration unchanged."); -636 if (force) -637 getLog().info("Generation/execution is forced!"); -638 else -639 { -640 getLog().info("Skipping schema generation!"); -641 project.getProperties().setProperty(SKIPPED, "true"); -642 return; -643 } -644 } -645 -646 -647 /** Truncate output file */ -648 try -649 { -650 new FileOutputStream(output).getChannel().truncate(0).close(); -651 } -652 catch (IOException e) -653 { -654 String error = -655 "Error while truncating " + output.getAbsolutePath() + ": " -656 + e.getMessage(); -657 getLog().warn(error); -658 throw new MojoExecutionException(error); -659 } -660 -661 /** Create a connection, if sufficient configuration infromation is available */ -662 connectionProvider.open(classLoaderService, properties); -663 -664 MetadataBuilder metadataBuilder = sources.getMetadataBuilder(); -665 -666 StrategySelector strategySelector = -667 serviceRegistry.getService(StrategySelector.class); -668 -669 if (properties.containsKey(IMPLICIT_NAMING_STRATEGY)) -670 { -671 metadataBuilder.applyImplicitNamingStrategy( -672 strategySelector.resolveStrategy( -673 ImplicitNamingStrategy.class, -674 properties.getProperty(IMPLICIT_NAMING_STRATEGY) -675 ) -676 ); -677 } -678 -679 if (properties.containsKey(PHYSICAL_NAMING_STRATEGY)) -680 { -681 metadataBuilder.applyPhysicalNamingStrategy( -682 strategySelector.resolveStrategy( -683 PhysicalNamingStrategy.class, -684 properties.getProperty(PHYSICAL_NAMING_STRATEGY) -685 ) -686 ); -687 } -688 -689 /** Prepare the generation of the SQL */ -690 Map settings = new HashMap(); -691 settings.putAll( -692 serviceRegistry -693 .getService(ConfigurationService.class) -694 .getSettings() -695 ); -696 ExceptionHandlerCollectingImpl handler = -697 new ExceptionHandlerCollectingImpl(); -698 ExecutionOptions options = -699 SchemaManagementToolCoordinator -700 .buildExecutionOptions(settings, handler); -701 final EnumSet<TargetType> targetTypes = EnumSet.of(TargetType.SCRIPT); -702 if (execute) -703 targetTypes.add(TargetType.DATABASE); -704 TargetDescriptor target = new TargetDescriptor() -705 { -706 @Override -707 public EnumSet<TargetType> getTargetTypes() -708 { -709 return targetTypes; -710 } -711 -712 @Override -713 public ScriptTargetOutput getScriptTargetOutput() -714 { -715 String charset = -716 (String) -717 serviceRegistry -718 .getService(ConfigurationService.class) -719 .getSettings() -720 .get(AvailableSettings.HBM2DDL_CHARSET_NAME); -721 return new ScriptTargetOutputToFile(output, charset); -722 } -723 }; -724 -725 /** -726 * Change class-loader of current thread. -727 * This is necessary, because still not all parts of Hibernate 5 use -728 * the newly introduced ClassLoaderService and will fail otherwise! -729 */ -730 Thread thread = Thread.currentThread(); -731 ClassLoader contextClassLoader = thread.getContextClassLoader(); -732 try -733 { -734 thread.setContextClassLoader(classLoader); -735 build((MetadataImplementor)metadataBuilder.build(), options, target); -736 if (handler.getExceptions().size() > 0) -737 { -738 StringBuilder builder = new StringBuilder(); -739 builder.append("Hibernate failed:"); -740 for (Exception e : handler.getExceptions()) -741 { -742 builder.append("\n * "); -743 builder.append(e.getMessage()); -744 AbstractSchemaMojo.printStrackTrace(builder, e); -745 builder.append("\n"); -746 } -747 String error = builder.toString(); -748 getLog().error(error); -749 throw new MojoFailureException(error); -750 } -751 } -752 finally -753 { -754 thread.setContextClassLoader(contextClassLoader); -755 /** Track, the content of the generated script */ -756 checkOutputFile(output, tracker); -757 } -758 } -759 catch (MojoExecutionException e) -760 { -761 tracker.failed(); -762 throw e; -763 } -764 catch (MojoFailureException e) -765 { -766 tracker.failed(); -767 throw e; -768 } -769 catch (RuntimeException e) -770 { -771 tracker.failed(); -772 throw e; -773 } -774 finally -775 { -776 /** Remember mappings and configuration */ -777 tracker.save(); -778 -779 /** Close the connection - if one was opened */ -780 connectionProvider.close(); -781 -782 /** Stop Log-Capturing */ -783 MavenLogAppender.endPluginLog(this); -784 } -785 } -786 -787 -788 abstract void build( -789 MetadataImplementor metadata, -790 ExecutionOptions options, -791 TargetDescriptor target -792 ) -793 throws -794 MojoFailureException, -795 MojoExecutionException; -796 -797 -798 private MutableClassLoader createClassLoader() throws MojoExecutionException -799 { -800 try -801 { -802 getLog().debug("Creating ClassLoader for project-dependencies..."); -803 LinkedHashSet<URL> urls = new LinkedHashSet<URL>(); -804 File file; -805 -806 file = new File(testOutputDirectory); -807 if (!file.exists()) -808 { -809 getLog().info("Creating test-output-directory: " + testOutputDirectory); -810 file.mkdirs(); -811 } -812 urls.add(file.toURI().toURL()); -813 -814 file = new File(outputDirectory); -815 if (!file.exists()) -816 { -817 getLog().info("Creating output-directory: " + outputDirectory); -818 file.mkdirs(); -819 } -820 urls.add(file.toURI().toURL()); -821 -822 return new MutableClassLoader(urls, getLog()); -823 } -824 catch (Exception e) -825 { -826 getLog().error("Error while creating ClassLoader!", e); -827 throw new MojoExecutionException(e.getMessage()); -828 } -829 } -830 -831 private void completeClassPath(MutableClassLoader classLoader) -832 throws -833 MojoExecutionException -834 { -835 try -836 { -837 getLog().debug("Completing class-paths of the ClassLoader for project-dependencies..."); -838 List<String> classpathFiles = project.getCompileClasspathElements(); -839 if (scanTestClasses) -840 classpathFiles.addAll(project.getTestClasspathElements()); -841 LinkedHashSet<URL> urls = new LinkedHashSet<URL>(); -842 for (String pathElement : classpathFiles) -843 { -844 getLog().debug("Dependency: " + pathElement); -845 urls.add(new File(pathElement).toURI().toURL()); -846 } -847 classLoader.add(urls); -848 } -849 catch (Exception e) -850 { -851 getLog().error("Error while creating ClassLoader!", e); -852 throw new MojoExecutionException(e.getMessage()); -853 } -854 } -855 -856 private Map loadProperties(ConfigLoader configLoader) -857 throws -858 MojoExecutionException -859 { -860 /** Try to read configuration from properties-file */ -861 if (hibernateProperties == null) -862 { -863 try -864 { -865 return configLoader.loadProperties("hibernate.properties"); -866 } -867 catch (ConfigurationException e) -868 { -869 getLog().debug(e.getMessage()); -870 return Collections.EMPTY_MAP; -871 } -872 } -873 else -874 { -875 try -876 { -877 File file = new File(hibernateProperties); -878 if (file.exists()) -879 { -880 getLog().info("Reading settings from file " + hibernateProperties + "..."); -881 return configLoader.loadProperties(file); -882 } -883 else -884 return configLoader.loadProperties(hibernateProperties); -885 } -886 catch (ConfigurationException e) -887 { -888 getLog().error("Error while reading properties!", e); -889 throw new MojoExecutionException(e.getMessage()); -890 } -891 } -892 } -893 -894 private LoadedConfig loadConfig(ConfigLoader configLoader) -895 throws MojoExecutionException -896 { -897 /** Try to read configuration from configuration-file */ -898 if (hibernateConfig == null) -899 { -900 try -901 { -902 return configLoader.loadConfigXmlResource("hibernate.cfg.xml"); -903 } -904 catch (ConfigurationException e) -905 { -906 getLog().debug(e.getMessage()); -907 return null; -908 } -909 } -910 else -911 { -912 try -913 { -914 File file = new File(hibernateConfig); -915 if (file.exists()) -916 { -917 getLog().info("Reading configuration from file " + hibernateConfig + "..."); -918 return configLoader.loadConfigXmlFile(file); -919 } -920 else -921 { -922 return configLoader.loadConfigXmlResource(hibernateConfig); -923 } -924 } -925 catch (ConfigurationException e) -926 { -927 getLog().error("Error while reading configuration!", e); -928 throw new MojoExecutionException(e.getMessage()); -929 } -930 } -931 } -932 -933 private void configure(Properties properties, ModificationTracker tracker) -934 throws MojoFailureException -935 { -936 /** -937 * Special treatment for the configuration-value "execute": if it is -938 * switched to "true", the genearation fo the schema should be forced! -939 */ -940 if (tracker.check(EXECUTE, execute.toString()) && execute) -941 { -942 getLog().info( -943 "hibernate.schema.execute was switched on: " + -944 "forcing generation/execution of SQL" -945 ); -946 tracker.touch(); -947 } -948 configure(properties, execute, EXECUTE); -949 -950 /** -951 * Configure the generation of the SQL. -952 * Overwrite values from properties-file if the configuration parameter is -953 * known to Hibernate. -954 */ -955 configure(properties, dialect, DIALECT); -956 configure(properties, delimiter, HBM2DDL_DELIMITER); -957 configure(properties, format, FORMAT_SQL); -958 configure(properties, createNamespaces, HBM2DLL_CREATE_NAMESPACES); -959 configure(properties, implicitNamingStrategy, IMPLICIT_NAMING_STRATEGY); -960 configure(properties, physicalNamingStrategy, PHYSICAL_NAMING_STRATEGY); -961 configure(properties, outputDirectory, OUTPUTDIRECTORY); -962 configure(properties, scanDependencies, SCAN_DEPENDENCIES); -963 configure(properties, scanTestClasses, SCAN_TESTCLASSES); -964 configure(properties, testOutputDirectory, TEST_OUTPUTDIRECTORY); -965 -966 /** -967 * Special treatment for the configuration-value "show": a change of its -968 * configured value should not lead to a regeneration of the database -969 * schama! -970 */ -971 if (show == null) -972 show = Boolean.valueOf(properties.getProperty(SHOW_SQL)); -973 else -974 properties.setProperty(SHOW_SQL, show.toString()); -975 -976 /** -977 * Configure the connection parameters. -978 * Overwrite values from properties-file. -979 */ -980 configure(properties, driver, DRIVER, JPA_JDBC_DRIVER); -981 configure(properties, url, URL, JPA_JDBC_URL); -982 configure(properties, username, USER, JPA_JDBC_USER); -983 configure(properties, password, PASS, JPA_JDBC_PASSWORD); -984 -985 if (properties.isEmpty()) -986 { -987 getLog().error("No properties set!"); -988 throw new MojoFailureException("Hibernate configuration is missing!"); -989 } -990 -991 getLog().info("Gathered configuration:"); -992 for (Entry<Object,Object> entry : properties.entrySet()) -993 getLog().info(" " + entry.getKey() + " = " + entry.getValue()); -994 } -995 -996 private void configure( -997 Properties properties, -998 String value, -999 String key, -1000 String alternativeKey -1001 ) -1002 { -1003 configure(properties, value, key); -1004 -1005 if (properties.containsKey(alternativeKey)) -1006 { -1007 if (properties.containsKey(key)) -1008 { -1009 getLog().warn( -1010 "Ignoring property " + alternativeKey + "=\"" + -1011 properties.getProperty(alternativeKey) + -1012 "\" in favour for property " + key + "=\"" + -1013 properties.getProperty(key) + "\"" -1014 ); -1015 properties.remove(alternativeKey); -1016 } -1017 else -1018 { -1019 value = properties.getProperty(alternativeKey); -1020 properties.remove(alternativeKey); -1021 getLog().info( -1022 "Using value \"" + value + "\" from property " + alternativeKey + -1023 " for property " + key -1024 ); -1025 properties.setProperty(key, value); -1026 } -1027 } -1028 } -1029 -1030 private void configure(Properties properties, String value, String key) -1031 { -1032 if (value != null) -1033 { -1034 if (properties.containsKey(key)) -1035 { -1036 if (!properties.getProperty(key).equals(value)) -1037 { -1038 getLog().info( -1039 "Overwriting property " + key + "=\"" + -1040 properties.getProperty(key) + -1041 "\" with value \"" + value + "\"" -1042 ); -1043 properties.setProperty(key, value); -1044 } -1045 } -1046 else -1047 { -1048 getLog().debug("Using value \"" + value + "\" for property " + key); -1049 properties.setProperty(key, value); -1050 } -1051 } -1052 } -1053 -1054 private void configure(Properties properties, Boolean value, String key) -1055 { -1056 configure(properties, value == null ? null : value.toString(), key); -1057 } -1058 -1059 private File getOutputFile(String filename) -1060 throws -1061 MojoExecutionException -1062 { -1063 File output = new File(filename); -1064 -1065 if (!output.isAbsolute()) -1066 { -1067 // Interpret relative file path relative to build directory -1068 output = new File(buildDirectory, filename); -1069 } -1070 getLog().debug("Output file: " + output.getPath()); -1071 -1072 // Ensure that directory path for specified file exists -1073 File outFileParentDir = output.getParentFile(); -1074 if (null != outFileParentDir && !outFileParentDir.exists()) -1075 { -1076 try -1077 { -1078 getLog().info( -1079 "Creating directory path for output file:" + -1080 outFileParentDir.getPath() -1081 ); -1082 outFileParentDir.mkdirs(); -1083 } -1084 catch (Exception e) -1085 { -1086 String error = -1087 "Error creating directory path for output file: " + e.getMessage(); -1088 getLog().error(error); -1089 throw new MojoExecutionException(error); -1090 } -1091 } -1092 -1093 try -1094 { -1095 output.createNewFile(); -1096 } -1097 catch (IOException e) -1098 { -1099 String error = "Error creating output file: " + e.getMessage(); -1100 getLog().error(error); -1101 throw new MojoExecutionException(error); -1102 } -1103 -1104 if (!output.canWrite()) -1105 { -1106 String error = -1107 "Output file " + output.getAbsolutePath() + " is not writable!"; -1108 getLog().error(error); -1109 throw new MojoExecutionException(error); -1110 } -1111 -1112 return output; -1113 } -1114 -1115 private void checkOutputFile(File output, ModificationTracker tracker) -1116 throws -1117 MojoExecutionException -1118 { -1119 try -1120 { -1121 if (output.exists()) -1122 tracker.track(SCRIPT, new FileInputStream(output)); -1123 else -1124 tracker.track(SCRIPT, ZonedDateTime.now().toString()); -1125 } -1126 catch (IOException e) -1127 { -1128 String error = -1129 "Error while checking the generated script: " + e.getMessage(); -1130 getLog().error(error); -1131 throw new MojoExecutionException(error); -1132 } -1133 } -1134 -1135 private void addMappings(MetadataSources sources, ModificationTracker tracker) -1136 throws MojoFailureException -1137 { -1138 getLog().debug("Adding explicitly configured mappings..."); -1139 if (mappings != null) -1140 { -1141 try -1142 { -1143 for (String filename : mappings.split("[\\s,]+")) -1144 { -1145 // First try the filename as absolute/relative path -1146 File file = new File(filename); -1147 if (!file.exists()) -1148 { -1149 // If the file was not found, search for it in the resource-directories -1150 for (Resource resource : project.getResources()) -1151 { -1152 file = new File(resource.getDirectory() + File.separator + filename); -1153 if (file.exists()) -1154 break; -1155 } -1156 } -1157 if (file.exists()) -1158 { -1159 if (file.isDirectory()) -1160 // TODO: add support to read all mappings under a directory -1161 throw new MojoFailureException(file.getAbsolutePath() + " is a directory"); -1162 if (tracker.track(filename, new FileInputStream(file))) -1163 getLog().debug("Found new or modified mapping-file: " + filename); -1164 else -1165 getLog().debug("Mapping-file unchanged: " + filename); -1166 -1167 sources.addFile(file); -1168 } -1169 else -1170 throw new MojoFailureException("File " + filename + " could not be found in any of the configured resource-directories!"); -1171 } -1172 } -1173 catch (IOException e) -1174 { -1175 throw new MojoFailureException("Cannot calculate MD5 sums!", e); -1176 } -1177 } -1178 } -1179 -1180 private void addRoot(Set<URL> urls, String path) throws MojoFailureException -1181 { -1182 try -1183 { -1184 File dir = new File(path); -1185 if (dir.exists()) -1186 { -1187 getLog().info("Adding " + dir.getAbsolutePath() + " to the list of roots to scan..."); -1188 urls.add(dir.toURI().toURL()); -1189 } -1190 else -1191 getLog().warn( -1192 "the directory cannot be scanned for annotated classes, " + -1193 "because it does not exist: " + -1194 dir.getAbsolutePath() -1195 ); -1196 } -1197 catch (MalformedURLException e) -1198 { -1199 getLog().error("error while adding the project-root to the list of roots to scan!", e); -1200 throw new MojoFailureException(e.getMessage()); -1201 } -1202 } -1203 -1204 private void addDependencies(Set<URL> urls) throws MojoFailureException -1205 { -1206 try -1207 { -1208 if (scanDependencies != null) -1209 { -1210 Matcher matcher = SPLIT.matcher(scanDependencies); -1211 while (matcher.find()) -1212 { -1213 getLog().info("Adding dependencies from scope " + matcher.group() + " to the list of roots to scan"); -1214 for (Artifact artifact : project.getDependencyArtifacts()) -1215 { -1216 if (!artifact.getScope().equalsIgnoreCase(matcher.group())) -1217 continue; -1218 if (artifact.getFile() == null) -1219 { -1220 getLog().warn("Cannot add dependency " + artifact.getId() + ": no JAR-file available!"); -1221 continue; -1222 } -1223 getLog().info("Adding dependencies from scope " + artifact.getId() + " to the list of roots to scan"); -1224 urls.add(artifact.getFile().toURI().toURL()); -1225 } -1226 } -1227 } -1228 } -1229 catch (MalformedURLException e) -1230 { -1231 getLog().error("Error while adding dependencies to the list of roots to scan!", e); -1232 throw new MojoFailureException(e.getMessage()); -1233 } -1234 } -1235 -1236 private Set<String> scanUrls(Set<URL> scanRoots) -1237 throws -1238 MojoFailureException -1239 { -1240 try -1241 { -1242 AnnotationDB db = new AnnotationDB(); -1243 for (URL root : scanRoots) -1244 db.scanArchives(root); -1245 -1246 Set<String> classes = new HashSet<String>(); -1247 if (db.getAnnotationIndex().containsKey(Entity.class.getName())) -1248 classes.addAll(db.getAnnotationIndex().get(Entity.class.getName())); -1249 if (db.getAnnotationIndex().containsKey(MappedSuperclass.class.getName())) -1250 classes.addAll(db.getAnnotationIndex().get(MappedSuperclass.class.getName())); -1251 if (db.getAnnotationIndex().containsKey(Embeddable.class.getName())) -1252 classes.addAll(db.getAnnotationIndex().get(Embeddable.class.getName())); -1253 -1254 return classes; -1255 } -1256 catch (Exception e) -1257 { -1258 getLog().error("Error while scanning!", e); -1259 throw new MojoFailureException(e.getMessage()); -1260 } -1261 } -1262 -1263 private void addAnnotated( -1264 String name, -1265 MetadataSources sources, -1266 ClassLoaderService classLoaderService, -1267 ModificationTracker tracker -1268 ) -1269 throws -1270 MojoFailureException, -1271 MojoExecutionException -1272 { -1273 try -1274 { -1275 getLog().info("Adding annotated resource: " + name); -1276 String packageName = null; -1277 -1278 boolean error = false; -1279 try -1280 { -1281 Class<?> annotatedClass = classLoaderService.classForName(name); -1282 String resourceName = annotatedClass.getName(); -1283 resourceName = -1284 resourceName.substring( -1285 resourceName.lastIndexOf(".") + 1, -1286 resourceName.length() -1287 ) + ".class"; -1288 InputStream is = annotatedClass.getResourceAsStream(resourceName); -1289 if (is != null) -1290 { -1291 if (tracker.track(name, is)) -1292 getLog().debug("New or modified class: " + name); -1293 else -1294 getLog().debug("Unchanged class: " + name); -1295 sources.addAnnotatedClass(annotatedClass); -1296 packageName = annotatedClass.getPackage().getName(); -1297 } -1298 else -1299 { -1300 getLog().error("cannot find ressource " + resourceName + " for class " + name); -1301 error = true; -1302 } -1303 } -1304 catch(ClassLoadingException e) -1305 { -1306 packageName = name; -1307 } -1308 if (error) -1309 { -1310 throw new MojoExecutionException("error while inspecting annotated class " + name); -1311 } -1312 -1313 while (packageName != null) -1314 { -1315 if (packages.contains(packageName)) -1316 return; -1317 String resource = packageName.replace('.', '/') + "/package-info.class"; -1318 InputStream is = classLoaderService.locateResourceStream(resource); -1319 if (is == null) -1320 { -1321 // No compiled package-info available: no package-level annotations! -1322 getLog().debug("Package " + packageName + " is not annotated."); -1323 } -1324 else -1325 { -1326 if (tracker.track(packageName, is)) -1327 getLog().debug("New or modified package: " + packageName); -1328 else -1329 getLog().debug("Unchanged package: " + packageName); -1330 getLog().info("Adding annotations from package " + packageName); -1331 sources.addPackage(packageName); -1332 } -1333 packages.add(packageName); -1334 int i = packageName.lastIndexOf('.'); -1335 if (i < 0) -1336 packageName = null; -1337 else -1338 packageName = packageName.substring(0,i); -1339 } -1340 } -1341 catch (Exception e) -1342 { -1343 getLog().error("Error while adding the annotated class " + name, e); -1344 throw new MojoFailureException(e.getMessage()); -1345 } -1346 } -1347 -1348 private ParsedPersistenceXmlDescriptor loadPersistenceUnit( -1349 ClassLoaderService classLoaderService, -1350 Properties properties -1351 ) -1352 throws -1353 MojoFailureException -1354 { -1355 PersistenceXmlParser parser = -1356 new PersistenceXmlParser( -1357 classLoaderService, -1358 PersistenceUnitTransactionType.RESOURCE_LOCAL -1359 ); -1360 -1361 Map<String, ParsedPersistenceXmlDescriptor> units = -1362 parser.doResolve(properties); -1363 -1364 if (persistenceUnit == null) -1365 { -1366 Iterator<String> names = units.keySet().iterator(); -1367 if (!names.hasNext()) -1368 { -1369 getLog().info("Found no META-INF/persistence.xml."); -1370 return null; -1371 } -1372 -1373 String name = names.next(); -1374 if (!names.hasNext()) -1375 { -1376 getLog().info("Using persistence-unit " + name); -1377 return units.get(name); -1378 } -1379 -1380 StringBuilder builder = new StringBuilder(); -1381 builder.append("No name provided and multiple persistence units found: "); -1382 builder.append(name); -1383 while(names.hasNext()) -1384 { -1385 builder.append(", "); -1386 builder.append(names.next()); -1387 } -1388 builder.append('.'); -1389 throw new MojoFailureException(builder.toString()); -1390 } -1391 -1392 if (units.containsKey(persistenceUnit)) -1393 { -1394 getLog().info("Using configured persistence-unit " + persistenceUnit); -1395 return units.get(persistenceUnit); -1396 } -1397 -1398 throw new MojoFailureException("Could not find persistence-unit " + persistenceUnit); -1399 } -1400 -1401 -1402 public static void printStrackTrace(StringBuilder builder, Throwable t) -1403 { -1404 while (t != null) -1405 { -1406 builder.append("\n\tCause: "); -1407 builder.append(t.getMessage() == null ? "" : t.getMessage().replaceAll("\\s+", " ")); -1408 for (StackTraceElement trace : t.getStackTrace()) -1409 { -1410 builder.append("\n\t"); -1411 builder.append(trace.getClassName()); -1412 builder.append("."); -1413 builder.append(trace.getMethodName()); -1414 builder.append("():"); -1415 builder.append(trace.getLineNumber()); -1416 } -1417 t = t.getCause(); -1418 } -1419 } -1420 } --