X-Git-Url: http://juplo.de/gitweb/?a=blobdiff_plain;f=dist%2Fhibernate4-maven-plugin-1.1.0%2Fxref%2Fde%2Fjuplo%2Fplugins%2Fhibernate4%2FHbm2DdlMojo.html;fp=dist%2Fhibernate4-maven-plugin-1.1.0%2Fxref%2Fde%2Fjuplo%2Fplugins%2Fhibernate4%2FHbm2DdlMojo.html;h=0000000000000000000000000000000000000000;hb=b293b312d6f0dd8b2dc716375fd442dd295a9942;hp=7f39b0f0b3e4e2aa9fcd28cbb8812cc6565d6a4f;hpb=9179a67d9952d3b63e95686dbd6cacd3c9e13cb2;p=website diff --git a/dist/hibernate4-maven-plugin-1.1.0/xref/de/juplo/plugins/hibernate4/Hbm2DdlMojo.html b/dist/hibernate4-maven-plugin-1.1.0/xref/de/juplo/plugins/hibernate4/Hbm2DdlMojo.html deleted file mode 100644 index 7f39b0f0..00000000 --- a/dist/hibernate4-maven-plugin-1.1.0/xref/de/juplo/plugins/hibernate4/Hbm2DdlMojo.html +++ /dev/null @@ -1,1320 +0,0 @@ - - -
--1 package de.juplo.plugins.hibernate4; -2 -3 /* -4 * Copyright 2001-2005 The Apache Software Foundation. -5 * -6 * Licensed under the Apache License, Version 2.0 (the "License"); -7 * you may not use this file except in compliance with the License. -8 * You may obtain a copy of the License at -9 * -10 * http://www.apache.org/licenses/LICENSE-2.0 -11 * -12 * Unless required by applicable law or agreed to in writing, software -13 * distributed under the License is distributed on an "AS IS" BASIS, -14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -15 * See the License for the specific language governing permissions and -16 * limitations under the License. -17 */ -18 -19 import com.pyx4j.log4j.MavenLogAppender; -20 import java.io.File; -21 import java.io.FileInputStream; -22 import java.io.FileNotFoundException; -23 import java.io.FileOutputStream; -24 import java.io.IOException; -25 import java.io.InputStream; -26 import java.io.ObjectInputStream; -27 import java.io.ObjectOutputStream; -28 import java.math.BigInteger; -29 import java.net.URL; -30 import java.net.URLClassLoader; -31 import java.security.MessageDigest; -32 import java.security.NoSuchAlgorithmException; -33 import java.sql.Driver; -34 import java.sql.DriverPropertyInfo; -35 import java.sql.SQLException; -36 import java.sql.SQLFeatureNotSupportedException; -37 import java.util.Collections; -38 import java.util.Comparator; -39 import java.util.HashMap; -40 import java.util.HashSet; -41 import java.util.LinkedHashSet; -42 import java.util.LinkedList; -43 import java.util.List; -44 import java.util.Map; -45 import java.util.Map.Entry; -46 import java.util.Properties; -47 import java.util.Set; -48 import java.util.TreeSet; -49 import java.util.logging.Logger; -50 import java.util.regex.Matcher; -51 import java.util.regex.Pattern; -52 import javax.persistence.Embeddable; -53 import javax.persistence.Entity; -54 import javax.persistence.MappedSuperclass; -55 import javax.persistence.spi.PersistenceUnitTransactionType; -56 import org.apache.maven.artifact.Artifact; -57 import org.apache.maven.model.Resource; -58 import org.apache.maven.plugin.AbstractMojo; -59 import org.apache.maven.plugin.MojoExecutionException; -60 import org.apache.maven.plugin.MojoFailureException; -61 import org.apache.maven.project.MavenProject; -62 import org.hibernate.boot.registry.StandardServiceRegistryBuilder; -63 import org.hibernate.boot.registry.classloading.spi.ClassLoaderService; -64 import org.hibernate.boot.registry.classloading.spi.ClassLoadingException; -65 import org.hibernate.boot.registry.internal.StandardServiceRegistryImpl; -66 import org.hibernate.cfg.Environment; -67 import org.hibernate.cfg.NamingStrategy; -68 import org.hibernate.envers.configuration.spi.AuditConfiguration; -69 import org.hibernate.internal.util.config.ConfigurationHelper; -70 import org.hibernate.jpa.boot.internal.ParsedPersistenceXmlDescriptor; -71 import org.hibernate.jpa.boot.internal.PersistenceXmlParser; -72 import org.hibernate.jpa.boot.spi.ProviderChecker; -73 import org.hibernate.tool.hbm2ddl.SchemaExport; -74 import org.hibernate.tool.hbm2ddl.SchemaExport.Type; -75 import org.hibernate.tool.hbm2ddl.Target; -76 import org.scannotation.AnnotationDB; -77 -78 -79 /** -80 * Goal which extracts the hibernate-mapping-configuration and -81 * exports an according SQL-database-schema. -82 * -83 * @goal export -84 * @phase process-classes -85 * @threadSafe -86 * @requiresDependencyResolution runtime -87 */ -88 public class Hbm2DdlMojo extends AbstractMojo -89 { -90 public final static String EXPORT_SKIPPED_PROPERTY = "hibernate.export.skipped"; -91 -92 public final static String DRIVER_CLASS = "hibernate.connection.driver_class"; -93 public final static String URL = "hibernate.connection.url"; -94 public final static String USERNAME = "hibernate.connection.username"; -95 public final static String PASSWORD = "hibernate.connection.password"; -96 public final static String DIALECT = "hibernate.dialect"; -97 public final static String NAMING_STRATEGY="hibernate.ejb.naming_strategy"; -98 public final static String ENVERS = "hibernate.export.envers"; -99 -100 public final static String JPA_DRIVER = "javax.persistence.jdbc.driver"; -101 public final static String JPA_URL = "javax.persistence.jdbc.url"; -102 public final static String JPA_USERNAME = "javax.persistence.jdbc.user"; -103 public final static String JPA_PASSWORD = "javax.persistence.jdbc.password"; -104 -105 public final static String MD5S = "hibernate4-generatedschema.md5s"; -106 -107 private final static Pattern split = Pattern.compile("[^,\\s]+"); -108 -109 -110 /** -111 * The maven project. -112 * <p> -113 * Only needed internally. -114 * -115 * @parameter property="project" -116 * @required -117 * @readonly -118 */ -119 private MavenProject project; -120 -121 /** -122 * Build-directory. -123 * <p> -124 * Only needed internally. -125 * -126 * @parameter property="project.build.directory" -127 * @required -128 * @readonly -129 */ -130 private String buildDirectory; -131 -132 /** -133 * Classes-Directory to scan. -134 * <p> -135 * This parameter defaults to the maven build-output-directory for classes. -136 * Additionally, all dependencies are scanned for annotated classes. -137 * -138 * @parameter property="project.build.outputDirectory" -139 * @since 1.0 -140 */ -141 private String outputDirectory; -142 -143 /** -144 * Whether to scan test-classes too, or not. -145 * <p> -146 * If this parameter is set to <code>true</code> the test-classes of the -147 * artifact will be scanned for hibernate-annotated classes additionally. -148 * -149 * @parameter property="hibernate.export.scan_testclasses" default-value="false" -150 * @since 1.0.1 -151 */ -152 private boolean scanTestClasses; -153 -154 /** -155 * Dependency-Scopes, that should be scanned for annotated classes. -156 * <p> -157 * By default, only dependencies in the scope <code>compile</code> are -158 * scanned for annotated classes. Multiple scopes can be seperated by -159 * white space or commas. -160 * <p> -161 * If you do not want any dependencies to be scanned for annotated -162 * classes, set this parameter to <code>none</code>. -163 * <p> -164 * The plugin does not scan for annotated classes in transitive -165 * dependencies. If some of your annotated classes are hidden in a -166 * transitive dependency, you can simply add that dependency explicitly. -167 * -168 * @parameter property="hibernate.export.scan_dependencies" default-value="compile" -169 * @since 1.0.3 -170 */ -171 private String scanDependencies; -172 -173 /** -174 * Test-Classes-Directory to scan. -175 * <p> -176 * This parameter defaults to the maven build-output-directory for -177 * test-classes. -178 * <p> -179 * This parameter is only used, when <code>scanTestClasses</code> is set -180 * to <code>true</code>! -181 * -182 * @parameter property="project.build.testOutputDirectory" -183 * @since 1.0.2 -184 */ -185 private String testOutputDirectory; -186 -187 /** -188 * Skip execution -189 * <p> -190 * If set to <code>true</code>, the execution is skipped. -191 * <p> -192 * A skipped execution is signaled via the maven-property -193 * <code>${hibernate.export.skipped}</code>. -194 * <p> -195 * The execution is skipped automatically, if no modified or newly added -196 * annotated classes are found and the dialect was not changed. -197 * -198 * @parameter property="hibernate.skip" default-value="${maven.test.skip}" -199 * @since 1.0 -200 */ -201 private boolean skip; -202 -203 /** -204 * Force execution -205 * <p> -206 * Force execution, even if no modified or newly added annotated classes -207 * where found and the dialect was not changed. -208 * <p> -209 * <code>skip</code> takes precedence over <code>force</code>. -210 * -211 * @parameter property="hibernate.export.force" default-value="false" -212 * @since 1.0 -213 */ -214 private boolean force; -215 -216 /** -217 * SQL-Driver name. -218 * -219 * @parameter property="hibernate.connection.driver_class" -220 * @since 1.0 -221 */ -222 private String driverClassName; -223 -224 /** -225 * Database URL. -226 * -227 * @parameter property="hibernate.connection.url" -228 * @since 1.0 -229 */ -230 private String url; -231 -232 /** -233 * Database username -234 * -235 * @parameter property="hibernate.connection.username" -236 * @since 1.0 -237 */ -238 private String username; -239 -240 /** -241 * Database password -242 * -243 * @parameter property="hibernate.connection.password" -244 * @since 1.0 -245 */ -246 private String password; -247 -248 /** -249 * Hibernate dialect. -250 * -251 * @parameter property="hibernate.dialect" -252 * @since 1.0 -253 */ -254 private String hibernateDialect; -255 -256 /** -257 * Hibernate Naming Strategy -258 * -259 * @parameter property="hibernate.ejb.naming_strategy" -260 * @since 1.0.2 -261 */ -262 private String hibernateNamingStrategy; -263 -264 /** -265 * Path to Hibernate properties file. -266 * If this parameter is not set the plugin will try to load the configuration -267 * from a file <code>hibernate.properties</code> on the classpath. The -268 * test-classpath takes precedence. -269 * -270 * @parameter -271 * @since 1.0 -272 */ -273 private String hibernateProperties; -274 -275 /** -276 * Path to Hibernate configuration file (.cfg.xml). -277 * Settings in this file will overwrite settings in the properties file. -278 * If this parameter is not set the plugin will try to load the configuration -279 * from a file <code>hibernate.cfg.xml</code> on the classpath. The -280 * test-classpath takes precedence. -281 * -282 * @parameter -283 * @since 1.1.0 -284 */ -285 private String hibernateConfig; -286 -287 /** -288 * Name of the persistence-unit. -289 * If there is only one persistence-unit available, that unit will be used -290 * automatically. -291 * Settings in this file will overwrite settings in the properties or the -292 * configuration file. -293 * -294 * @parameter -295 * @since 1.1.0 -296 */ -297 private String persistenceUnit; -298 -299 /** -300 * List of Hibernate-Mapping-Files (XML). -301 * Multiple files can be separated with white-spaces and/or commas. -302 * -303 * @parameter property="hibernate.mapping" -304 * @since 1.0.2 -305 */ -306 private String hibernateMapping; -307 -308 /** -309 * Target of execution: -310 * <ul> -311 * <li><strong>NONE</strong> only export schema to SQL-script (forces execution, signals skip)</li> -312 * <li><strong>EXPORT</strong> create database (<strong>DEFAULT!</strong>). forces execution, signals skip)</li> -313 * <li><strong>SCRIPT</strong> export schema to SQL-script and print it to STDOUT</li> -314 * <li><strong>BOTH</strong></li> -315 * </ul> -316 * -317 * A database connection is only needed for EXPORT and BOTH, but a -318 * Hibernate-Dialect must always be chosen. -319 * -320 * @parameter property="hibernate.export.target" default-value="EXPORT" -321 * @since 1.0 -322 */ -323 private String target; -324 -325 /** -326 * Type of execution. -327 * <ul> -328 * <li><strong>NONE</strong> do nothing - just validate the configuration</li> -329 * <li><strong>CREATE</strong> create database-schema</li> -330 * <li><strong>DROP</strong> drop database-schema</li> -331 * <li><strong>BOTH</strong> (<strong>DEFAULT!</strong>)</li> -332 * </ul> -333 * -334 * If NONE is choosen, no databaseconnection is needed. -335 * -336 * @parameter property="hibernate.export.type" default-value="BOTH" -337 * @since 1.0 -338 */ -339 private String type; -340 -341 /** -342 * Output file. -343 * -344 * @parameter property="hibernate.export.schema.filename" default-value="${project.build.directory}/schema.sql" -345 * @since 1.0 -346 */ -347 private String outputFile; -348 -349 /** -350 * Delimiter in output-file. -351 * -352 * @parameter property="hibernate.export.schema.delimiter" default-value=";" -353 * @since 1.0 -354 */ -355 private String delimiter; -356 -357 /** -358 * Format output-file. -359 * -360 * @parameter property="hibernate.export.schema.format" default-value="true" -361 * @since 1.0 -362 */ -363 private boolean format; -364 -365 /** -366 * Generate envers schema for auditing tables. -367 * -368 * @parameter property="hibernate.export.envers" default-value="true" -369 * @since 1.0.3 -370 */ -371 private boolean envers; -372 -373 -374 @Override -375 public void execute() -376 throws -377 MojoFailureException, -378 MojoExecutionException -379 { -380 if (skip) -381 { -382 getLog().info("Execution of hibernate4-maven-plugin:export was skipped!"); -383 project.getProperties().setProperty(EXPORT_SKIPPED_PROPERTY, "true"); -384 return; -385 } -386 -387 Map<String,String> md5s; -388 boolean modified = false; -389 File saved = new File(buildDirectory + File.separator + MD5S); -390 -391 if (saved.isFile() && saved.length() > 0) -392 { -393 try -394 { -395 FileInputStream fis = new FileInputStream(saved); -396 ObjectInputStream ois = new ObjectInputStream(fis); -397 md5s = (HashMap<String,String>)ois.readObject(); -398 ois.close(); -399 } -400 catch (Exception e) -401 { -402 md5s = new HashMap<String,String>(); -403 getLog().warn("Cannot read timestamps from saved: " + e); -404 } -405 } -406 else -407 { -408 md5s = new HashMap<String,String>(); -409 try -410 { -411 saved.createNewFile(); -412 } -413 catch (IOException e) -414 { -415 getLog().debug("Cannot create file \"" + saved.getPath() + "\" for timestamps: " + e); -416 } -417 } -418 -419 URLClassLoader classLoader = null; -420 try -421 { -422 getLog().debug("Creating ClassLoader for project-dependencies..."); -423 List<String> classpathFiles = project.getCompileClasspathElements(); -424 if (scanTestClasses) -425 classpathFiles.addAll(project.getTestClasspathElements()); -426 List<URL> urls = new LinkedList<URL>(); -427 File file; -428 file = new File(testOutputDirectory); -429 if (!file.exists()) -430 { -431 getLog().info("creating test-output-directory: " + testOutputDirectory); -432 file.mkdirs(); -433 } -434 urls.add(file.toURI().toURL()); -435 file = new File(outputDirectory); -436 if (!file.exists()) -437 { -438 getLog().info("creating output-directory: " + outputDirectory); -439 file.mkdirs(); -440 } -441 urls.add(file.toURI().toURL()); -442 for (String pathElement : classpathFiles) -443 { -444 getLog().debug("Dependency: " + pathElement); -445 urls.add(new File(pathElement).toURI().toURL()); -446 } -447 classLoader = -448 new URLClassLoader( -449 urls.toArray(new URL[urls.size()]), -450 getClass().getClassLoader() -451 ); -452 } -453 catch (Exception e) -454 { -455 getLog().error("Error while creating ClassLoader!", e); -456 throw new MojoExecutionException(e.getMessage()); -457 } -458 -459 Set<Class<?>> classes = -460 new TreeSet<Class<?>>( -461 new Comparator<Class<?>>() { -462 @Override -463 public int compare(Class<?> a, Class<?> b) -464 { -465 return a.getName().compareTo(b.getName()); -466 } -467 } -468 ); -469 -470 try -471 { -472 AnnotationDB db = new AnnotationDB(); -473 File dir = new File(outputDirectory); -474 if (dir.exists()) -475 { -476 getLog().info("Scanning directory " + outputDirectory + " for annotated classes..."); -477 URL dirUrl = dir.toURI().toURL(); -478 db.scanArchives(dirUrl); -479 } -480 if (scanTestClasses) -481 { -482 dir = new File(testOutputDirectory); -483 if (dir.exists()) -484 { -485 getLog().info("Scanning directory " + testOutputDirectory + " for annotated classes..."); -486 URL dirUrl = dir.toURI().toURL(); -487 db.scanArchives(dirUrl); -488 } -489 } -490 if (scanDependencies != null) -491 { -492 Matcher matcher = split.matcher(scanDependencies); -493 while (matcher.find()) -494 { -495 getLog().info("Scanning dependencies for scope " + matcher.group()); -496 for (Artifact artifact : project.getDependencyArtifacts()) -497 { -498 if (!artifact.getScope().equalsIgnoreCase(matcher.group())) -499 continue; -500 if (artifact.getFile() == null) -501 { -502 getLog().warn( -503 "Cannot scan dependency " + -504 artifact.getId() + -505 ": no JAR-file available!" -506 ); -507 continue; -508 } -509 getLog().info( -510 "Scanning dependency " + -511 artifact.getId() + -512 " for annotated classes..." -513 ); -514 db.scanArchives(artifact.getFile().toURI().toURL()); -515 } -516 } -517 } -518 -519 Set<String> classNames = new HashSet<String>(); -520 if (db.getAnnotationIndex().containsKey(Entity.class.getName())) -521 classNames.addAll(db.getAnnotationIndex().get(Entity.class.getName())); -522 if (db.getAnnotationIndex().containsKey(MappedSuperclass.class.getName())) -523 classNames.addAll(db.getAnnotationIndex().get(MappedSuperclass.class.getName())); -524 if (db.getAnnotationIndex().containsKey(Embeddable.class.getName())) -525 classNames.addAll(db.getAnnotationIndex().get(Embeddable.class.getName())); -526 -527 MessageDigest digest = java.security.MessageDigest.getInstance("MD5"); -528 for (String name : classNames) -529 { -530 Class<?> annotatedClass = classLoader.loadClass(name); -531 classes.add(annotatedClass); -532 String resourceName = annotatedClass.getName(); -533 resourceName = resourceName.substring(resourceName.lastIndexOf(".") + 1, resourceName.length()) + ".class"; -534 InputStream is = -535 annotatedClass -536 .getResourceAsStream(resourceName); -537 byte[] buffer = new byte[1024*4]; // copy data in 4MB-chunks -538 int i; -539 while((i = is.read(buffer)) > -1) -540 digest.update(buffer, 0, i); -541 is.close(); -542 byte[] bytes = digest.digest(); -543 BigInteger bi = new BigInteger(1, bytes); -544 String newMd5 = String.format("%0" + (bytes.length << 1) + "x", bi); -545 String oldMd5 = !md5s.containsKey(name) ? "" : md5s.get(name); -546 if (!newMd5.equals(oldMd5)) -547 { -548 getLog().debug("Found new or modified annotated class: " + name); -549 modified = true; -550 md5s.put(name, newMd5); -551 } -552 else -553 { -554 getLog().debug(oldMd5 + " -> class unchanged: " + name); -555 } -556 } -557 } -558 catch (ClassNotFoundException e) -559 { -560 getLog().error("Error while adding annotated classes!", e); -561 throw new MojoExecutionException(e.getMessage()); -562 } -563 catch (Exception e) -564 { -565 getLog().error("Error while scanning!", e); -566 throw new MojoFailureException(e.getMessage()); -567 } -568 -569 -570 ValidationConfiguration config = new ValidationConfiguration(); -571 // Clear unused system-properties -572 config.setProperties(new Properties()); -573 -574 -575 ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader(); -576 StandardServiceRegistryImpl registry = null; -577 MavenLogAppender.startPluginLog(this); -578 -579 try -580 { -581 /** -582 * Change class-loader of current thread, so that hibernate can -583 * see all dependencies! -584 */ -585 Thread.currentThread().setContextClassLoader(classLoader); -586 -587 -588 /** Try to read configuration from properties-file */ -589 try -590 { -591 if (hibernateProperties == null) -592 { -593 URL url = classLoader.findResource("hibernate.properties"); -594 if (url == null) -595 { -596 getLog().info("No hibernate.properties on the classpath!"); -597 } -598 else -599 { -600 getLog().info("Reading settings from hibernate.properties on the classpath."); -601 Properties properties = new Properties(); -602 properties.load(url.openStream()); -603 config.setProperties(properties); -604 } -605 } -606 else -607 { -608 File file = new File(hibernateProperties); -609 if (file.exists()) -610 { -611 getLog().info("Reading settings from file " + hibernateProperties + "..."); -612 Properties properties = new Properties(); -613 properties.load(new FileInputStream(file)); -614 config.setProperties(properties); -615 } -616 else -617 getLog().info("No hibernate-properties-file found! (Checked path: " + hibernateProperties + ")"); -618 } -619 } -620 catch (IOException e) -621 { -622 getLog().error("Error while reading properties!", e); -623 throw new MojoExecutionException(e.getMessage()); -624 } -625 -626 /** Try to read configuration from configuration-file */ -627 try -628 { -629 if (hibernateConfig == null) -630 { -631 URL url = classLoader.findResource("hibernate.cfg.xml"); -632 if (url == null) -633 { -634 getLog().info("No hibernate.cfg.xml on the classpath!"); -635 } -636 else -637 { -638 getLog().info("Reading settings from hibernate.cfg.xml on the classpath."); -639 config.configure(url); -640 } -641 } -642 else -643 { -644 File file = new File(hibernateConfig); -645 if (file.exists()) -646 { -647 getLog().info("Reading configuration from file " + hibernateConfig + "..."); -648 config.configure(file); -649 } -650 else -651 getLog().info("No hibernate-configuration-file found! (Checked path: " + hibernateConfig + ")"); -652 } -653 } -654 catch (Exception e) -655 { -656 getLog().error("Error while reading configuration!", e); -657 throw new MojoExecutionException(e.getMessage()); -658 } -659 -660 ParsedPersistenceXmlDescriptor persistenceUnitDescriptor = -661 getPersistenceUnitDescriptor( -662 persistenceUnit, -663 config.getProperties(), -664 new MavenProjectClassLoaderService(classLoader) -665 ); -666 if (persistenceUnitDescriptor != null) -667 config.setProperties(persistenceUnitDescriptor.getProperties()); -668 -669 -670 /** Overwrite values from properties-file or set, if given */ -671 -672 if (driverClassName != null) -673 { -674 if (config.getProperties().containsKey(DRIVER_CLASS)) -675 getLog().debug( -676 "Overwriting property " + -677 DRIVER_CLASS + "=" + config.getProperty(DRIVER_CLASS) + -678 " with the value " + driverClassName -679 ); -680 else -681 getLog().debug("Using the value " + driverClassName); -682 config.setProperty(DRIVER_CLASS, driverClassName); -683 } -684 if (config.getProperty(DRIVER_CLASS) == null) -685 { -686 String driver = config.getProperty(JPA_DRIVER); -687 if (driver != null) -688 { -689 getLog().info( -690 DRIVER_CLASS + -691 " is not set. Borrow setting from " + -692 JPA_DRIVER + -693 ": " + -694 driver); -695 config.setProperty(DRIVER_CLASS, driver); -696 } -697 } -698 -699 if (url != null) -700 { -701 if (config.getProperties().containsKey(URL)) -702 getLog().debug( -703 "Overwriting property " + -704 URL + "=" + config.getProperty(URL) + -705 " with the value " + url -706 ); -707 else -708 getLog().debug("Using the value " + url); -709 config.setProperty(URL, url); -710 } -711 if (config.getProperty(URL) == null) -712 { -713 String url = config.getProperty(JPA_URL); -714 if (url != null) -715 { -716 getLog().info( -717 URL + -718 " is not set. Borrow setting from " + -719 JPA_URL + -720 ": " + -721 url); -722 config.setProperty(URL, url); -723 } -724 } -725 -726 if (username != null) -727 { -728 if (config.getProperties().containsKey(USERNAME)) -729 getLog().debug( -730 "Overwriting property " + -731 USERNAME + "=" + config.getProperty(USERNAME) + -732 " with the value " + username -733 ); -734 else -735 getLog().debug("Using the value " + username); -736 config.setProperty(USERNAME, username); -737 } -738 if (config.getProperty(USERNAME) == null) -739 { -740 String username = config.getProperty(JPA_USERNAME); -741 if (username != null) -742 { -743 getLog().info( -744 USERNAME + -745 " is not set. Borrow setting from " + -746 JPA_USERNAME + -747 ": " + -748 username); -749 config.setProperty(USERNAME, username); -750 } -751 } -752 -753 if (password != null) -754 { -755 if (config.getProperties().containsKey(PASSWORD)) -756 getLog().debug( -757 "Overwriting property " + -758 PASSWORD + "=" + config.getProperty(PASSWORD) + -759 " with value " + password -760 ); -761 else -762 getLog().debug("Using value " + password + " for property " + PASSWORD); -763 config.setProperty(PASSWORD, password); -764 } -765 if (config.getProperty(PASSWORD) == null) -766 { -767 String password = config.getProperty(JPA_PASSWORD); -768 if (password != null) -769 { -770 getLog().info( -771 PASSWORD + -772 " is not set. Borrow setting from " + -773 JPA_PASSWORD + -774 ": " + -775 password); -776 config.setProperty(PASSWORD, password); -777 } -778 } -779 -780 if (hibernateDialect != null) -781 { -782 if (config.getProperties().containsKey(DIALECT)) -783 getLog().debug( -784 "Overwriting property " + -785 DIALECT + "=" + config.getProperty(DIALECT) + -786 " with value " + hibernateDialect -787 ); -788 else -789 getLog().debug( -790 "Using value " + hibernateDialect + " for property " + DIALECT -791 ); -792 config.setProperty(DIALECT, hibernateDialect); -793 } -794 -795 if ( hibernateNamingStrategy != null ) -796 { -797 if ( config.getProperties().contains(NAMING_STRATEGY)) -798 getLog().debug( -799 "Overwriting property " + -800 NAMING_STRATEGY + "=" + config.getProperty(NAMING_STRATEGY) + -801 " with value " + hibernateNamingStrategy -802 ); -803 else -804 getLog().debug( -805 "Using value " + hibernateNamingStrategy + " for property " + -806 NAMING_STRATEGY -807 ); -808 config.setProperty(NAMING_STRATEGY, hibernateNamingStrategy); -809 } -810 -811 /** The generated SQL varies with the dialect! */ -812 if (md5s.containsKey(DIALECT)) -813 { -814 String dialect = config.getProperty(DIALECT); -815 if (md5s.get(DIALECT).equals(dialect)) -816 getLog().debug("SQL-dialect unchanged."); -817 else -818 { -819 modified = true; -820 if (dialect == null) -821 { -822 getLog().debug("SQL-dialect was unset."); -823 md5s.remove(DIALECT); -824 } -825 else -826 { -827 getLog().debug("SQL-dialect changed: " + dialect); -828 md5s.put(DIALECT, dialect); -829 } -830 } -831 } -832 else -833 { -834 String dialect = config.getProperty(DIALECT); -835 if (dialect != null) -836 { -837 modified = true; -838 md5s.put(DIALECT, config.getProperty(DIALECT)); -839 } -840 } -841 -842 /** The generated SQL varies with the envers-configuration */ -843 if (md5s.get(ENVERS) != null) -844 { -845 if (md5s.get(ENVERS).equals(Boolean.toString(envers))) -846 getLog().debug("Envers-Configuration unchanged. Enabled: " + envers); -847 else -848 { -849 getLog().debug("Envers-Configuration changed. Enabled: " + envers); -850 modified = true; -851 md5s.put(ENVERS, Boolean.toString(envers)); -852 } -853 } -854 else -855 { -856 modified = true; -857 md5s.put(ENVERS, Boolean.toString(envers)); -858 } -859 -860 if (config.getProperties().isEmpty()) -861 { -862 getLog().error("No properties set!"); -863 throw new MojoFailureException("Hibernate configuration is missing!"); -864 } -865 -866 getLog().info("Gathered hibernate-configuration (turn on debugging for details):"); -867 for (Entry<Object,Object> entry : config.getProperties().entrySet()) -868 getLog().info(" " + entry.getKey() + " = " + entry.getValue()); -869 -870 -871 getLog().debug("Adding explicitly configured mappings..."); -872 if (hibernateMapping != null) -873 { -874 try -875 { -876 MessageDigest digest = java.security.MessageDigest.getInstance("MD5"); -877 for (String filename : hibernateMapping.split("[\\s,]+")) -878 { -879 // First try the filename as absolute/relative path -880 File file = new File(filename); -881 if (!file.exists()) -882 { -883 // If the file was not found, search for it in the resource-directories -884 for (Resource resource : project.getResources()) -885 { -886 file = new File(resource.getDirectory() + File.separator + filename); -887 if (file.exists()) -888 break; -889 } -890 } -891 if (file != null && file.exists()) -892 { -893 InputStream is = new FileInputStream(file); -894 byte[] buffer = new byte[1024*4]; // copy data in 4MB-chunks -895 int i; -896 while((i = is.read(buffer)) > -1) -897 digest.update(buffer, 0, i); -898 is.close(); -899 byte[] bytes = digest.digest(); -900 BigInteger bi = new BigInteger(1, bytes); -901 String newMd5 = String.format("%0" + (bytes.length << 1) + "x", bi); -902 String oldMd5 = !md5s.containsKey(filename) ? "" : md5s.get(filename); -903 if (!newMd5.equals(oldMd5)) -904 { -905 getLog().debug("Found new or modified mapping-file: " + filename); -906 modified = true; -907 md5s.put(filename, newMd5); -908 } -909 else -910 { -911 getLog().debug(oldMd5 + " -> mapping-file unchanged: " + filename); -912 } -913 getLog().debug("Adding mappings from XML-configurationfile: " + file); -914 config.addFile(file); -915 } -916 else -917 throw new MojoFailureException("File " + filename + " could not be found in any of the configured resource-directories!"); -918 } -919 } -920 catch (NoSuchAlgorithmException e) -921 { -922 throw new MojoFailureException("Cannot calculate MD5 sums!", e); -923 } -924 catch (FileNotFoundException e) -925 { -926 throw new MojoFailureException("Cannot calculate MD5 sums!", e); -927 } -928 catch (IOException e) -929 { -930 throw new MojoFailureException("Cannot calculate MD5 sums!", e); -931 } -932 } -933 -934 getLog().debug("Adding annotated classes to hibernate-mapping-configuration..."); -935 // build annotated packages -936 Set<String> packages = new HashSet<String>(); -937 for (Class<?> annotatedClass : classes) -938 { -939 String packageName = annotatedClass.getPackage().getName(); -940 if (!packages.contains(packageName)) -941 { -942 getLog().debug("Add package " + packageName); -943 packages.add(packageName); -944 config.addPackage(packageName); -945 getLog().debug("type definintions" + config.getTypeDefs()); -946 } -947 getLog().debug("Class " + annotatedClass); -948 config.addAnnotatedClass(annotatedClass); -949 } -950 -951 Target target = null; -952 try -953 { -954 target = Target.valueOf(this.target.toUpperCase()); -955 } -956 catch (IllegalArgumentException e) -957 { -958 getLog().error("Invalid value for configuration-option \"target\": " + this.target); -959 getLog().error("Valid values are: NONE, SCRIPT, EXPORT, BOTH"); -960 throw new MojoExecutionException("Invalid value for configuration-option \"target\""); -961 } -962 Type type = null; -963 try -964 { -965 type = Type.valueOf(this.type.toUpperCase()); -966 } -967 catch (IllegalArgumentException e) -968 { -969 getLog().error("Invalid value for configuration-option \"type\": " + this.type); -970 getLog().error("Valid values are: NONE, CREATE, DROP, BOTH"); -971 throw new MojoExecutionException("Invalid value for configuration-option \"type\""); -972 } -973 -974 -975 if (config.getProperty(DIALECT) == null) -976 throw new MojoFailureException("hibernate-dialect must be set!"); -977 -978 -979 if (target.equals(Target.SCRIPT) || target.equals(Target.NONE)) -980 { -981 project.getProperties().setProperty(EXPORT_SKIPPED_PROPERTY, "true"); -982 } -983 if ( -984 !modified -985 && !target.equals(Target.SCRIPT) -986 && !target.equals(Target.NONE) -987 && !force -988 ) -989 { -990 getLog().info("No modified annotated classes or mapping-files found and dialect unchanged."); -991 getLog().info("Skipping schema generation!"); -992 project.getProperties().setProperty(EXPORT_SKIPPED_PROPERTY, "true"); -993 return; -994 } -995 -996 -997 if ( config.getProperties().containsKey(NAMING_STRATEGY)) -998 { -999 String namingStrategy = config.getProperty(NAMING_STRATEGY); -1000 getLog().debug("Explicitly set NamingStrategy: " + namingStrategy); -1001 try -1002 { -1003 @SuppressWarnings("unchecked") -1004 Class<NamingStrategy> namingStrategyClass = (Class<NamingStrategy>) Class.forName(namingStrategy); -1005 config.setNamingStrategy(namingStrategyClass.newInstance()); -1006 } -1007 catch (Exception e) -1008 { -1009 getLog().error("Error setting NamingStrategy", e); -1010 throw new MojoExecutionException(e.getMessage()); -1011 } -1012 } -1013 -1014 -1015 Environment.verifyProperties(config.getProperties()); -1016 ConfigurationHelper.resolvePlaceHolders(config.getProperties()); -1017 registry = -1018 (StandardServiceRegistryImpl) -1019 new StandardServiceRegistryBuilder() -1020 .applySettings(config.getProperties()) -1021 .build(); -1022 -1023 config.buildMappings(); -1024 -1025 if (envers) -1026 { -1027 getLog().info("Automatic auditing via hibernate-envers enabled!"); -1028 AuditConfiguration.getFor(config); -1029 } -1030 -1031 SchemaExport export = new SchemaExport(registry, config); -1032 export.setDelimiter(delimiter); -1033 export.setFormat(format); -1034 -1035 File outF = new File(outputFile); -1036 -1037 if (!outF.isAbsolute()) -1038 { -1039 // Interpret relative file path relative to build directory -1040 outF = new File(buildDirectory, outputFile); -1041 getLog().info("Adjusted relative path, resulting path is " + outF.getPath()); -1042 } -1043 -1044 // Ensure that directory path for specified file exists -1045 File outFileParentDir = outF.getParentFile(); -1046 if (null != outFileParentDir && !outFileParentDir.exists()) -1047 { -1048 try -1049 { -1050 getLog().info("Creating directory path for output file:" + outFileParentDir.getPath()); -1051 outFileParentDir.mkdirs(); -1052 } -1053 catch (Exception e) -1054 { -1055 getLog().error("Error creating directory path for output file: " + e.getLocalizedMessage()); -1056 } -1057 } -1058 -1059 export.setOutputFile(outF.getPath()); -1060 export.execute(target, type); -1061 -1062 for (Object exception : export.getExceptions()) -1063 getLog().debug(exception.toString()); -1064 } -1065 finally -1066 { -1067 /** Stop Log-Capturing */ -1068 MavenLogAppender.endPluginLog(this); -1069 -1070 /** Restore the old class-loader (TODO: is this really necessary?) */ -1071 Thread.currentThread().setContextClassLoader(contextClassLoader); -1072 -1073 if (registry != null) -1074 registry.destroy(); -1075 } -1076 -1077 /** Write md5-sums for annotated classes to file */ -1078 try -1079 { -1080 FileOutputStream fos = new FileOutputStream(saved); -1081 ObjectOutputStream oos = new ObjectOutputStream(fos); -1082 oos.writeObject(md5s); -1083 oos.close(); -1084 fos.close(); -1085 } -1086 catch (Exception e) -1087 { -1088 getLog().error("Cannot write md5-sums to file: " + e); -1089 } -1090 } -1091 -1092 private ParsedPersistenceXmlDescriptor getPersistenceUnitDescriptor( -1093 String name, -1094 Properties properties, -1095 ClassLoaderService loader -1096 ) -1097 throws -1098 MojoFailureException -1099 { -1100 PersistenceXmlParser parser = -1101 new PersistenceXmlParser( -1102 loader, -1103 PersistenceUnitTransactionType.RESOURCE_LOCAL -1104 ); -1105 -1106 List<ParsedPersistenceXmlDescriptor> units = parser.doResolve(properties); -1107 -1108 if (name == null) -1109 { -1110 switch (units.size()) -1111 { -1112 case 0: -1113 getLog().info("Found no META-INF/persistence.xml."); -1114 return null; -1115 case 1: -1116 getLog().info("Using persistence-unit " + units.get(0).getName()); -1117 return units.get(0); -1118 default: -1119 getLog().warn("No name provided and multiple persistence units found:"); -1120 for (ParsedPersistenceXmlDescriptor unit : units) -1121 getLog().warn(" - " + unit.getName()); -1122 return null; -1123 } -1124 -1125 } -1126 -1127 for (ParsedPersistenceXmlDescriptor unit : units) -1128 { -1129 getLog().debug("Found persistence-unit " + unit.getName()); -1130 if (!unit.getName().equals(name)) -1131 continue; -1132 -1133 // See if we (Hibernate) are the persistence provider -1134 if (!ProviderChecker.isProvider(unit, properties)) -1135 { -1136 getLog().debug("Wrong provider: " + unit.getProviderClassName()); -1137 continue; -1138 } -1139 -1140 getLog().info("Using persistence-unit " + unit.getName()); -1141 return unit; -1142 } -1143 -1144 throw new MojoFailureException("Could not find persistence-unit " + name); -1145 } -1146 -1147 -1148 static final class MavenProjectClassLoaderService implements ClassLoaderService -1149 { -1150 final private ClassLoader loader; -1151 -1152 -1153 public MavenProjectClassLoaderService(ClassLoader loader) -1154 { -1155 this.loader = loader; -1156 } -1157 -1158 -1159 @Override -1160 public <T> Class<T> classForName(String name) -1161 { -1162 try -1163 { -1164 return (Class<T>)loader.loadClass(name); -1165 } -1166 catch (ClassNotFoundException e) -1167 { -1168 throw new ClassLoadingException( "Unable to load class [" + name + "]", e ); -1169 } -1170 } -1171 -1172 @Override -1173 public URL locateResource(String name) -1174 { -1175 return loader.getResource(name); -1176 } -1177 -1178 @Override -1179 public InputStream locateResourceStream(String name) -1180 { -1181 return loader.getResourceAsStream(name); -1182 } -1183 -1184 @Override -1185 public List<URL> locateResources(String name) -1186 { -1187 try -1188 { -1189 return Collections.list(loader.getResources(name)); -1190 } -1191 catch (IOException e) -1192 { -1193 return Collections.EMPTY_LIST; -1194 } -1195 } -1196 -1197 @Override -1198 public <S> LinkedHashSet<S> loadJavaServices(Class<S> serviceContract) -1199 { -1200 throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. -1201 } -1202 -1203 @Override -1204 public void stop() { } -1205 -1206 } -1207 -1208 -1209 /** -1210 * Needed, because DriverManager won't pick up drivers, that were not -1211 * loaded by the system-classloader! -1212 * See: -1213 * http://stackoverflow.com/questions/288828/how-to-use-a-jdbc-driver-fromodifiedm-an-arbitrary-location -1214 */ -1215 static final class DriverProxy implements Driver -1216 { -1217 private final Driver target; -1218 -1219 DriverProxy(Driver target) -1220 { -1221 if (target == null) -1222 throw new NullPointerException(); -1223 this.target = target; -1224 } -1225 -1226 public java.sql.Driver getTarget() -1227 { -1228 return target; -1229 } -1230 -1231 @Override -1232 public boolean acceptsURL(String url) throws SQLException -1233 { -1234 return target.acceptsURL(url); -1235 } -1236 -1237 @Override -1238 public java.sql.Connection connect( -1239 String url, -1240 java.util.Properties info -1241 ) -1242 throws -1243 SQLException -1244 { -1245 return target.connect(url, info); -1246 } -1247 -1248 @Override -1249 public int getMajorVersion() -1250 { -1251 return target.getMajorVersion(); -1252 } -1253 -1254 @Override -1255 public int getMinorVersion() -1256 { -1257 return target.getMinorVersion(); -1258 } -1259 -1260 @Override -1261 public DriverPropertyInfo[] getPropertyInfo( -1262 String url, -1263 Properties info -1264 ) -1265 throws -1266 SQLException -1267 { -1268 return target.getPropertyInfo(url, info); -1269 } -1270 -1271 @Override -1272 public boolean jdbcCompliant() -1273 { -1274 return target.jdbcCompliant(); -1275 } -1276 -1277 /** -1278 * This Method cannot be annotated with @Override, becaus the plugin -1279 * will not compile then under Java 1.6! -1280 */ -1281 public Logger getParentLogger() throws SQLFeatureNotSupportedException -1282 { -1283 throw new SQLFeatureNotSupportedException("Not supported, for backward-compatibility with Java 1.6"); -1284 } -1285 -1286 @Override -1287 public String toString() -1288 { -1289 return "Proxy: " + target; -1290 } -1291 -1292 @Override -1293 public int hashCode() -1294 { -1295 return target.hashCode(); -1296 } -1297 -1298 @Override -1299 public boolean equals(Object obj) -1300 { -1301 if (!(obj instanceof DriverProxy)) -1302 return false; -1303 DriverProxy other = (DriverProxy) obj; -1304 return this.target.equals(other.target); -1305 } -1306 } -1307 } --