X-Git-Url: https://juplo.de/gitweb/?a=blobdiff_plain;f=dist%2Fhibernate4-maven-plugin-1.0.2%2Fxref%2Fde%2Fjuplo%2Fplugins%2Fhibernate4%2FHbm2DdlMojo.html;fp=dist%2Fhibernate4-maven-plugin-1.0.2%2Fxref%2Fde%2Fjuplo%2Fplugins%2Fhibernate4%2FHbm2DdlMojo.html;h=fa2488ce59054583c460a10861ff8593d6943c65;hb=a53595184bd6e57bdc45292cc92c393c4e2dfe6e;hp=0000000000000000000000000000000000000000;hpb=c48c9ee0e9faa89a4c0a5323b367b9f5a6abe602;p=website diff --git a/dist/hibernate4-maven-plugin-1.0.2/xref/de/juplo/plugins/hibernate4/Hbm2DdlMojo.html b/dist/hibernate4-maven-plugin-1.0.2/xref/de/juplo/plugins/hibernate4/Hbm2DdlMojo.html new file mode 100644 index 00000000..fa2488ce --- /dev/null +++ b/dist/hibernate4-maven-plugin-1.0.2/xref/de/juplo/plugins/hibernate4/Hbm2DdlMojo.html @@ -0,0 +1,908 @@ + + + + +Hbm2DdlMojo xref + + + +
View Javadoc
+
+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.Connection;
+34  import java.sql.Driver;
+35  import java.sql.DriverManager;
+36  import java.sql.DriverPropertyInfo;
+37  import java.sql.SQLException;
+38  import java.sql.SQLFeatureNotSupportedException;
+39  import java.util.Comparator;
+40  import java.util.Enumeration;
+41  import java.util.HashMap;
+42  import java.util.HashSet;
+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 javax.persistence.Embeddable;
+51  import javax.persistence.Entity;
+52  import javax.persistence.MappedSuperclass;
+53  import org.apache.maven.model.Resource;
+54  import org.apache.maven.plugin.AbstractMojo;
+55  import org.apache.maven.plugin.MojoExecutionException;
+56  import org.apache.maven.plugin.MojoFailureException;
+57  import org.apache.maven.project.MavenProject;
+58  import org.hibernate.cfg.Configuration;
+59  import org.hibernate.cfg.NamingStrategy;
+60  import org.hibernate.tool.hbm2ddl.SchemaExport;
+61  import org.hibernate.tool.hbm2ddl.SchemaExport.Type;
+62  import org.hibernate.tool.hbm2ddl.Target;
+63  import org.scannotation.AnnotationDB;
+64  
+65  
+66  /**
+67   * Goal which extracts the hibernate-mapping-configuration and
+68   * exports an according SQL-database-schema.
+69   *
+70   * @goal export
+71   * @phase process-classes
+72   * @threadSafe
+73   * @requiresDependencyResolution runtime
+74   */
+75  public class Hbm2DdlMojo extends AbstractMojo
+76  {
+77    public final static String EXPORT_SKIPPED_PROPERTY = "hibernate.export.skipped";
+78  
+79    public final static String DRIVER_CLASS = "hibernate.connection.driver_class";
+80    public final static String URL = "hibernate.connection.url";
+81    public final static String USERNAME = "hibernate.connection.username";
+82    public final static String PASSWORD = "hibernate.connection.password";
+83    public final static String DIALECT = "hibernate.dialect";
+84    public final static String NAMING_STRATEGY="hibernate.ejb.naming_strategy";
+85  
+86    private final static String MD5S = "schema.md5s";
+87  
+88    /**
+89     * The maven project.
+90     * <p>
+91     * Only needed internally.
+92     *
+93     * @parameter property="project"
+94     * @required
+95     * @readonly
+96     */
+97    private MavenProject project;
+98  
+99    /**
+100    * Build-directory.
+101    * <p>
+102    * Only needed internally.
+103    *
+104    * @parameter property="project.build.directory"
+105    * @required
+106    * @readonly
+107    */
+108   private String buildDirectory;
+109 
+110   /**
+111    * Classes-Directory to scan.
+112    * <p>
+113    * This parameter defaults to the maven build-output-directory for classes.
+114    * Additonally, all dependencies are scanned for annotated classes.
+115    *
+116    * @parameter property="project.build.outputDirectory"
+117    */
+118   private String outputDirectory;
+119 
+120   /**
+121    * Wether to scan test-classes too, or not.
+122    * <p>
+123    * If this parameter is set to <code>true</code> the test-classes of the
+124    * artifact will be scanned for hibernate-annotated classes additionally.
+125    *
+126    * @parameter property="hibernate.export.scan_testclasses" default-value="false"
+127    */
+128   private boolean scanTestClasses;
+129 
+130   /**
+131    * Test-Classes-Directory to scan.
+132    * <p>
+133    * This parameter defaults to the maven build-output-directory for
+134    * test-classes.
+135    * <p>
+136    * This parameter is only used, when <code>scanTestClasses</code> is set
+137    * to <code>true</code>!
+138    *
+139    * @parameter property="project.build.testOutputDirectory"
+140    */
+141   private String testOutputDirectory;
+142 
+143   /**
+144    * Skip execution
+145    * <p>
+146    * If set to <code>true</code>, the execution is skipped.
+147    * <p>
+148    * A skipped excecution is signaled via the maven-property
+149    * <code>${hibernate.export.skipped}</code>.
+150    * <p>
+151    * The excecution is skipped automatically, if no modified or newly added
+152    * annotated classes are found and the dialect was not changed.
+153    *
+154    * @parameter property="maven.test.skip" default-value="false"
+155    */
+156   private boolean skip;
+157 
+158   /**
+159    * Force execution
+160    * <p>
+161    * Force execution, even if no modified or newly added annotated classes
+162    * where found and the dialect was not changed.
+163    * <p>
+164    * <code>skip</code> takes precedence over <code>force</code>.
+165    *
+166    * @parameter property="hibernate.export.force" default-value="false"
+167    */
+168   private boolean force;
+169 
+170   /**
+171    * SQL-Driver name.
+172    *
+173    * @parameter property="hibernate.connection.driver_class"
+174    */
+175   private String driverClassName;
+176 
+177   /**
+178    * Database URL.
+179    *
+180    * @parameter property="hibernate.connection.url"
+181    */
+182   private String url;
+183 
+184   /**
+185    * Database username
+186    *
+187    * @parameter property="hibernate.connection.username"
+188    */
+189   private String username;
+190 
+191   /**
+192    * Database password
+193    *
+194    * @parameter property="hibernate.connection.password"
+195    */
+196   private String password;
+197 
+198   /**
+199    * Hibernate dialect.
+200    *
+201    * @parameter property="hibernate.dialect"
+202    */
+203   private String hibernateDialect;
+204 
+205   /**
+206    * Hibernate Naming Strategy
+207    * @parameter property="hibernate.ejb.naming_strategy"
+208    */
+209   private String hibernateNamingStrategy;
+210 
+211   /**
+212    * Path to Hibernate configuration file.
+213    *
+214    * @parameter default-value="${project.build.outputDirectory}/hibernate.properties"
+215    */
+216   private String hibernateProperties;
+217 
+218   /**
+219    * List of Hibernate-Mapping-Files (XML).
+220    * Multiple files can be separated with white-spaces and/or commas.
+221    *
+222    * @parameter property="hibernate.mapping"
+223    */
+224   private String hibernateMapping;
+225 
+226   /**
+227    * Target of execution:
+228    * <ul>
+229    *   <li><strong>NONE</strong> only export schema to SQL-script (forces excecution, signals skip)</li>
+230    *   <li><strong>EXPORT</strong> create database (<strong>DEFAULT!</strong>). forces excecution, signals skip)</li>
+231    *   <li><strong>SCRIPT</strong> export schema to SQL-script and print it to STDOUT</li>
+232    *   <li><strong>BOTH</strong></li>
+233    * </ul>
+234    *
+235    * A databaseconnection is only needed for EXPORT and BOTH, but a
+236    * Hibernate-Dialect must always be choosen.
+237    *
+238    * @parameter property="hibernate.export.target" default-value="EXPORT"
+239    */
+240   private String target;
+241 
+242   /**
+243    * Type of execution.
+244    * <ul>
+245    *   <li><strong>NONE</strong> do nothing - just validate the configuration</li>
+246    *   <li><strong>CREATE</strong> create database-schema</li>
+247    *   <li><strong>DROP</strong> drop database-schema</li>
+248    *   <li><strong>BOTH</strong> (<strong>DEFAULT!</strong>)</li>
+249    * </ul>
+250    *
+251    * If NONE is choosen, no databaseconnection is needed.
+252    *
+253    * @parameter property="hibernate.export.type" default-value="BOTH"
+254    */
+255   private String type;
+256 
+257   /**
+258    * Output file.
+259    *
+260    * @parameter property="hibernate.export.schema.filename" default-value="${project.build.directory}/schema.sql"
+261    */
+262   private String outputFile;
+263 
+264   /**
+265    * Delimiter in output-file.
+266    *
+267    * @parameter property="hibernate.export.schema.delimiter" default-value=";"
+268    */
+269   private String delimiter;
+270 
+271   /**
+272    * Format output-file.
+273    *
+274    * @parameter property="hibernate.export.schema.format" default-value="true"
+275    */
+276   private boolean format;
+277 
+278 
+279   @Override
+280   public void execute()
+281     throws
+282       MojoFailureException,
+283       MojoExecutionException
+284   {
+285     if (skip)
+286     {
+287       getLog().info("Exectuion of hibernate4-maven-plugin:export was skipped!");
+288       project.getProperties().setProperty(EXPORT_SKIPPED_PROPERTY, "true");
+289       return;
+290     }
+291 
+292     File dir = new File(outputDirectory);
+293     if (!dir.exists())
+294       throw new MojoExecutionException("Cannot scan for annotated classes in " + outputDirectory + ": directory does not exist!");
+295 
+296     Map<String,String> md5s;
+297     boolean modified = false;
+298     File saved = new File(buildDirectory + File.separator + MD5S);
+299 
+300     if (saved.exists())
+301     {
+302       try
+303       {
+304         FileInputStream fis = new FileInputStream(saved);
+305         ObjectInputStream ois = new ObjectInputStream(fis);
+306         md5s = (HashMap<String,String>)ois.readObject();
+307         ois.close();
+308       }
+309       catch (Exception e)
+310       {
+311         md5s = new HashMap<String,String>();
+312         getLog().warn("Cannot read timestamps from saved: " + e);
+313       }
+314     }
+315     else
+316     {
+317       md5s = new HashMap<String,String>();
+318       try
+319       {
+320         saved.createNewFile();
+321       }
+322       catch (IOException e)
+323       {
+324         getLog().warn("Cannot create saved for timestamps: " + e);
+325       }
+326     }
+327 
+328     ClassLoader classLoader = null;
+329     try
+330     {
+331       getLog().debug("Creating ClassLoader for project-dependencies...");
+332       List<String> classpathFiles = project.getCompileClasspathElements();
+333       if (scanTestClasses)
+334         classpathFiles.addAll(project.getTestClasspathElements());
+335       URL[] urls = new URL[classpathFiles.size()];
+336       for (int i = 0; i < classpathFiles.size(); ++i)
+337       {
+338         getLog().debug("Dependency: " + classpathFiles.get(i));
+339         urls[i] = new File(classpathFiles.get(i)).toURI().toURL();
+340       }
+341       classLoader = new URLClassLoader(urls, getClass().getClassLoader());
+342     }
+343     catch (Exception e)
+344     {
+345       getLog().error("Error while creating ClassLoader!", e);
+346       throw new MojoExecutionException(e.getMessage());
+347     }
+348 
+349     Set<Class<?>> classes =
+350         new TreeSet<Class<?>>(
+351             new Comparator<Class<?>>() {
+352               @Override
+353               public int compare(Class<?> a, Class<?> b)
+354               {
+355                 return a.getName().compareTo(b.getName());
+356               }
+357             }
+358           );
+359 
+360     try
+361     {
+362       AnnotationDB db = new AnnotationDB();
+363       getLog().info("Scanning directory " + outputDirectory + " for annotated classes...");
+364       URL dirUrl = dir.toURI().toURL();
+365       db.scanArchives(dirUrl);
+366       if (scanTestClasses)
+367       {
+368         dir = new File(testOutputDirectory);
+369         if (!dir.exists())
+370           throw new MojoExecutionException("Cannot scan for annotated test-classes in " + testOutputDirectory + ": directory does not exist!");
+371         getLog().info("Scanning directory " + testOutputDirectory + " for annotated classes...");
+372         dirUrl = dir.toURI().toURL();
+373         db.scanArchives(dirUrl);
+374       }
+375 
+376       Set<String> classNames = new HashSet<String>();
+377       if (db.getAnnotationIndex().containsKey(Entity.class.getName()))
+378         classNames.addAll(db.getAnnotationIndex().get(Entity.class.getName()));
+379       if (db.getAnnotationIndex().containsKey(MappedSuperclass.class.getName()))
+380         classNames.addAll(db.getAnnotationIndex().get(MappedSuperclass.class.getName()));
+381       if (db.getAnnotationIndex().containsKey(Embeddable.class.getName()))
+382         classNames.addAll(db.getAnnotationIndex().get(Embeddable.class.getName()));
+383 
+384       MessageDigest digest = java.security.MessageDigest.getInstance("MD5");
+385       for (String name : classNames)
+386       {
+387         Class<?> annotatedClass = classLoader.loadClass(name);
+388         classes.add(annotatedClass);
+389         InputStream is =
+390             annotatedClass
+391                 .getResourceAsStream(annotatedClass.getSimpleName() + ".class");
+392         byte[] buffer = new byte[1024*4]; // copy data in 4MB-chunks
+393         int i;
+394         while((i = is.read(buffer)) > -1)
+395           digest.update(buffer, 0, i);
+396         is.close();
+397         byte[] bytes = digest.digest();
+398         BigInteger bi = new BigInteger(1, bytes);
+399         String newMd5 = String.format("%0" + (bytes.length << 1) + "x", bi);
+400         String oldMd5 = !md5s.containsKey(name) ? "" : md5s.get(name);
+401         if (!newMd5.equals(oldMd5))
+402         {
+403           getLog().debug("Found new or modified annotated class: " + name);
+404           modified = true;
+405           md5s.put(name, newMd5);
+406         }
+407         else
+408         {
+409           getLog().debug(oldMd5 + " -> class unchanged: " + name);
+410         }
+411       }
+412     }
+413     catch (ClassNotFoundException e)
+414     {
+415       getLog().error("Error while adding annotated classes!", e);
+416       throw new MojoExecutionException(e.getMessage());
+417     }
+418     catch (Exception e)
+419     {
+420       getLog().error("Error while scanning!", e);
+421       throw new MojoFailureException(e.getMessage());
+422     }
+423 
+424     if (classes.isEmpty())
+425     {
+426       if (hibernateMapping == null || hibernateMapping.isEmpty())
+427         throw new MojoFailureException("No annotated classes found in directory " + outputDirectory);
+428     }
+429     else
+430     {
+431       getLog().debug("Detected classes with mapping-annotations:");
+432       for (Class<?> annotatedClass : classes)
+433         getLog().debug("  " + annotatedClass.getName());
+434     }
+435 
+436 
+437     Properties properties = new Properties();
+438 
+439     /** Try to read configuration from properties-file */
+440     try
+441     {
+442       File file = new File(hibernateProperties);
+443       if (file.exists())
+444       {
+445         getLog().info("Reading properties from file " + hibernateProperties + "...");
+446         properties.load(new FileInputStream(file));
+447       }
+448       else
+449         getLog().info("No hibernate-properties-file found! (Checked path: " + hibernateProperties + ")");
+450     }
+451     catch (IOException e)
+452     {
+453       getLog().error("Error while reading properties!", e);
+454       throw new MojoExecutionException(e.getMessage());
+455     }
+456 
+457     /** Overwrite values from propertie-file or set, if given */
+458     if (driverClassName != null)
+459     {
+460       if (properties.containsKey(DRIVER_CLASS))
+461         getLog().debug(
+462             "Overwriting property " +
+463             DRIVER_CLASS + "=" + properties.getProperty(DRIVER_CLASS) +
+464             " with the value " + driverClassName
+465           );
+466       else
+467         getLog().debug("Using the value " + driverClassName);
+468       properties.setProperty(DRIVER_CLASS, driverClassName);
+469     }
+470     if (url != null)
+471     {
+472       if (properties.containsKey(URL))
+473         getLog().debug(
+474             "Overwriting property " +
+475             URL + "=" + properties.getProperty(URL) +
+476             " with the value " + url
+477           );
+478       else
+479         getLog().debug("Using the value " + url);
+480       properties.setProperty(URL, url);
+481     }
+482     if (username != null)
+483     {
+484       if (properties.containsKey(USERNAME))
+485         getLog().debug(
+486             "Overwriting property " +
+487             USERNAME + "=" + properties.getProperty(USERNAME) +
+488             " with the value " + username
+489           );
+490       else
+491         getLog().debug("Using the value " + username);
+492       properties.setProperty(USERNAME, username);
+493     }
+494     if (password != null)
+495     {
+496       if (properties.containsKey(PASSWORD))
+497         getLog().debug(
+498             "Overwriting property " +
+499             PASSWORD + "=" + properties.getProperty(PASSWORD) +
+500             " with the value " + password
+501           );
+502       else
+503         getLog().debug("Using the value " + password);
+504       properties.setProperty(PASSWORD, password);
+505     }
+506     if (hibernateDialect != null)
+507     {
+508       if (properties.containsKey(DIALECT))
+509         getLog().debug(
+510             "Overwriting property " +
+511             DIALECT + "=" + properties.getProperty(DIALECT) +
+512             " with the value " + hibernateDialect
+513           );
+514       else
+515         getLog().debug("Using the value " + hibernateDialect);
+516       properties.setProperty(DIALECT, hibernateDialect);
+517     }
+518     if ( hibernateNamingStrategy != null )
+519     {
+520       if ( properties.contains(NAMING_STRATEGY))
+521         getLog().debug(
+522             "Overwriting property " +
+523             NAMING_STRATEGY + "=" + properties.getProperty(NAMING_STRATEGY) +
+524             " with the value " + hibernateNamingStrategy
+525            );
+526       else
+527         getLog().debug("Using the value " + hibernateNamingStrategy);
+528       properties.setProperty(NAMING_STRATEGY, hibernateNamingStrategy);
+529     }
+530 
+531     /** The generated SQL varies with the dialect! */
+532     if (md5s.containsKey(DIALECT))
+533     {
+534       String dialect = properties.getProperty(DIALECT);
+535       if (md5s.get(DIALECT).equals(dialect))
+536         getLog().debug("SQL-dialect unchanged.");
+537       else
+538       {
+539         getLog().debug("SQL-dialect changed: " + dialect);
+540         modified = true;
+541         md5s.put(DIALECT, dialect);
+542       }
+543     }
+544     else
+545     {
+546       modified = true;
+547       md5s.put(DIALECT, properties.getProperty(DIALECT));
+548     }
+549 
+550     if (properties.isEmpty())
+551     {
+552       getLog().error("No properties set!");
+553       throw new MojoFailureException("Hibernate-Configuration is missing!");
+554     }
+555 
+556     Configuration config = new Configuration();
+557     config.setProperties(properties);
+558 
+559     if ( properties.containsKey(NAMING_STRATEGY))
+560     {
+561       String namingStrategy = properties.getProperty(NAMING_STRATEGY);
+562       getLog().debug("Explicitly set NamingStrategy: " + namingStrategy);
+563       try
+564       {
+565         @SuppressWarnings("unchecked")
+566         Class<NamingStrategy> namingStrategyClass = (Class<NamingStrategy>) Class.forName(namingStrategy);
+567         config.setNamingStrategy(namingStrategyClass.newInstance());
+568       }
+569       catch (Exception e)
+570       {
+571         getLog().error("Error setting NamingStrategy", e);
+572         throw new MojoExecutionException(e.getMessage());
+573       }
+574     }
+575 
+576     getLog().debug("Adding annotated classes to hibernate-mapping-configuration...");
+577     for (Class<?> annotatedClass : classes)
+578     {
+579       getLog().debug("Class " + annotatedClass);
+580       config.addAnnotatedClass(annotatedClass);
+581     }
+582 
+583     if (hibernateMapping != null)
+584     {
+585       try
+586       {
+587         MessageDigest digest = java.security.MessageDigest.getInstance("MD5");
+588         for (String filename : hibernateMapping.split("[\\s,]+"))
+589         {
+590           // First try the filename as absolute/relative path
+591           File file = new File(filename);
+592           if (!file.exists())
+593           {
+594             // If the file was not found, search for it in the resource-directories
+595             for (Resource resource : project.getResources())
+596             {
+597               file = new File(resource.getDirectory() + File.separator + filename);
+598               if (file.exists())
+599                 break;
+600             }
+601           }
+602           if (file != null && file.exists())
+603           {
+604             InputStream is = new FileInputStream(file);
+605             byte[] buffer = new byte[1024*4]; // copy data in 4MB-chunks
+606             int i;
+607             while((i = is.read(buffer)) > -1)
+608               digest.update(buffer, 0, i);
+609             is.close();
+610             byte[] bytes = digest.digest();
+611             BigInteger bi = new BigInteger(1, bytes);
+612             String newMd5 = String.format("%0" + (bytes.length << 1) + "x", bi);
+613             String oldMd5 = !md5s.containsKey(filename) ? "" : md5s.get(filename);
+614             if (!newMd5.equals(oldMd5))
+615             {
+616               getLog().debug("Found new or modified mapping-file: " + filename);
+617               modified = true;
+618               md5s.put(filename, newMd5);
+619             }
+620             else
+621             {
+622               getLog().debug(oldMd5 + " -> mapping-file unchanged: " + filename);
+623             }
+624             getLog().debug("Adding mappings from XML-configurationfile: " + file);
+625             config.addFile(file);
+626           }
+627           else
+628             throw new MojoFailureException("File " + filename + " could not be found in any of the configured resource-directories!");
+629         }
+630       }
+631       catch (NoSuchAlgorithmException e)
+632       {
+633         throw new MojoFailureException("Cannot calculate MD5-summs!", e);
+634       }
+635       catch (FileNotFoundException e)
+636       {
+637         throw new MojoFailureException("Cannot calculate MD5-summs!", e);
+638       }
+639       catch (IOException e)
+640       {
+641         throw new MojoFailureException("Cannot calculate MD5-summs!", e);
+642       }
+643     }
+644 
+645     Target target = null;
+646     try
+647     {
+648       target = Target.valueOf(this.target.toUpperCase());
+649     }
+650     catch (IllegalArgumentException e)
+651     {
+652       getLog().error("Invalid value for configuration-option \"target\": " + this.target);
+653       getLog().error("Valid values are: NONE, SCRIPT, EXPORT, BOTH");
+654       throw new MojoExecutionException("Invalid value for configuration-option \"target\"");
+655     }
+656     Type type = null;
+657     try
+658     {
+659       type = Type.valueOf(this.type.toUpperCase());
+660     }
+661     catch (IllegalArgumentException e)
+662     {
+663       getLog().error("Invalid value for configuration-option \"type\": " + this.type);
+664       getLog().error("Valid values are: NONE, CREATE, DROP, BOTH");
+665       throw new MojoExecutionException("Invalid value for configuration-option \"type\"");
+666     }
+667 
+668     if (target.equals(Target.SCRIPT) || target.equals(Target.NONE))
+669     {
+670       project.getProperties().setProperty(EXPORT_SKIPPED_PROPERTY, "true");
+671     }
+672     if (
+673         !modified
+674         && !target.equals(Target.SCRIPT)
+675         && !target.equals(Target.NONE)
+676         && !force
+677       )
+678     {
+679       getLog().info("No modified annotated classes or mapping-files found and dialect unchanged.");
+680       getLog().info("Skipping schema generation!");
+681       project.getProperties().setProperty(EXPORT_SKIPPED_PROPERTY, "true");
+682       return;
+683     }
+684 
+685     getLog().info("Gathered hibernate-configuration (turn on debugging for details):");
+686     for (Entry<Object,Object> entry : properties.entrySet())
+687       getLog().info("  " + entry.getKey() + " = " + entry.getValue());
+688 
+689     Connection connection = null;
+690     try
+691     {
+692       /**
+693        * The connection must be established outside of hibernate, because
+694        * hibernate does not use the context-classloader of the current
+695        * thread and, hence, would not be able to resolve the driver-class!
+696        */
+697       getLog().debug("Target: " + target + ", Type: " + type);
+698       switch (target)
+699       {
+700         case EXPORT:
+701         case BOTH:
+702           switch (type)
+703           {
+704             case CREATE:
+705             case DROP:
+706             case BOTH:
+707               Class driverClass = classLoader.loadClass(properties.getProperty(DRIVER_CLASS));
+708               getLog().debug("Registering JDBC-driver " + driverClass.getName());
+709               DriverManager.registerDriver(new DriverProxy((Driver)driverClass.newInstance()));
+710               getLog().debug(
+711                   "Opening JDBC-connection to "
+712                   + properties.getProperty(URL)
+713                   + " as "
+714                   + properties.getProperty(USERNAME)
+715                   + " with password "
+716                   + properties.getProperty(PASSWORD)
+717                   );
+718               connection = DriverManager.getConnection(
+719                   properties.getProperty(URL),
+720                   properties.getProperty(USERNAME),
+721                   properties.getProperty(PASSWORD)
+722                   );
+723           }
+724       }
+725     }
+726     catch (ClassNotFoundException e)
+727     {
+728       getLog().error("Dependency for driver-class " + properties.getProperty(DRIVER_CLASS) + " is missing!");
+729       throw new MojoExecutionException(e.getMessage());
+730     }
+731     catch (Exception e)
+732     {
+733       getLog().error("Cannot establish connection to database!");
+734       Enumeration<Driver> drivers = DriverManager.getDrivers();
+735       if (!drivers.hasMoreElements())
+736         getLog().error("No drivers registered!");
+737       while (drivers.hasMoreElements())
+738         getLog().debug("Driver: " + drivers.nextElement());
+739       throw new MojoExecutionException(e.getMessage());
+740     }
+741 
+742     ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
+743     MavenLogAppender.startPluginLog(this);
+744     try
+745     {
+746       /**
+747        * Change class-loader of current thread, so that hibernate can
+748        * see all dependencies!
+749        */
+750       Thread.currentThread().setContextClassLoader(classLoader);
+751 
+752       SchemaExport export = new SchemaExport(config, connection);
+753       export.setOutputFile(outputFile);
+754       export.setDelimiter(delimiter);
+755       export.setFormat(format);
+756       export.execute(target, type);
+757 
+758       for (Object exception : export.getExceptions())
+759         getLog().debug(exception.toString());
+760     }
+761     finally
+762     {
+763       /** Stop Log-Capturing */
+764       MavenLogAppender.endPluginLog(this);
+765 
+766       /** Restore the old class-loader (TODO: is this really necessary?) */
+767       Thread.currentThread().setContextClassLoader(contextClassLoader);
+768 
+769       /** Close the connection */
+770       try
+771       {
+772         if (connection != null)
+773           connection.close();
+774       }
+775       catch (SQLException e)
+776       {
+777         getLog().error("Error while closing connection: " + e.getMessage());
+778       }
+779     }
+780 
+781     /** Write md5-sums for annotated classes to file */
+782     try
+783     {
+784       FileOutputStream fos = new FileOutputStream(saved);
+785       ObjectOutputStream oos = new ObjectOutputStream(fos);
+786       oos.writeObject(md5s);
+787       oos.close();
+788       fos.close();
+789     }
+790     catch (Exception e)
+791     {
+792       getLog().error("Cannot write md5-sums to file: " + e);
+793     }
+794   }
+795 
+796   /**
+797    * Needed, because DriverManager won't pick up drivers, that were not
+798    * loaded by the system-classloader!
+799    * See:
+800    * http://stackoverflow.com/questions/288828/how-to-use-a-jdbc-driver-fromodifiedm-an-arbitrary-location
+801    */
+802   static final class DriverProxy implements Driver
+803   {
+804     private final Driver target;
+805 
+806     DriverProxy(Driver target)
+807     {
+808       if (target == null)
+809         throw new NullPointerException();
+810       this.target = target;
+811     }
+812 
+813     public java.sql.Driver getTarget()
+814     {
+815       return target;
+816     }
+817 
+818     @Override
+819     public boolean acceptsURL(String url) throws SQLException
+820     {
+821       return target.acceptsURL(url);
+822     }
+823 
+824     @Override
+825     public java.sql.Connection connect(
+826         String url,
+827         java.util.Properties info
+828       )
+829       throws
+830         SQLException
+831     {
+832       return target.connect(url, info);
+833     }
+834 
+835     @Override
+836     public int getMajorVersion()
+837     {
+838       return target.getMajorVersion();
+839     }
+840 
+841     @Override
+842     public int getMinorVersion()
+843     {
+844       return target.getMinorVersion();
+845     }
+846 
+847     @Override
+848     public DriverPropertyInfo[] getPropertyInfo(
+849         String url,
+850         Properties info
+851       )
+852       throws
+853         SQLException
+854     {
+855       return target.getPropertyInfo(url, info);
+856     }
+857 
+858     @Override
+859     public boolean jdbcCompliant()
+860     {
+861       return target.jdbcCompliant();
+862     }
+863 
+864     /**
+865      * This Method cannot be annotated with @Override, becaus the plugin
+866      * will not compile then under Java 1.6!
+867      */
+868     public Logger getParentLogger() throws SQLFeatureNotSupportedException
+869     {
+870       throw new SQLFeatureNotSupportedException("Not supported, for backward-compatibility with Java 1.6");
+871     }
+872 
+873     @Override
+874     public String toString()
+875     {
+876       return "Proxy: " + target;
+877     }
+878 
+879     @Override
+880     public int hashCode()
+881     {
+882       return target.hashCode();
+883     }
+884 
+885     @Override
+886     public boolean equals(Object obj)
+887     {
+888       if (!(obj instanceof DriverProxy))
+889         return false;
+890       DriverProxy other = (DriverProxy) obj;
+891       return this.target.equals(other.target);
+892     }
+893   }
+894 }
+
+
+ +