/* * eID Applet Project. * Copyright (C) 2010 FedICT. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License version * 3.0 as published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, see * http://www.gnu.org/licenses/. */ package be.fedict.eid.applet.maven.sql.ddl; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; import java.util.ArrayList; import java.util.List; import java.util.Set; import javax.persistence.Entity; import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.factory.ArtifactFactory; import org.apache.maven.artifact.resolver.ArtifactNotFoundException; import org.apache.maven.artifact.resolver.ArtifactResolutionException; import org.apache.maven.artifact.resolver.ArtifactResolver; import org.apache.maven.artifact.versioning.VersionRange; import org.apache.maven.model.Dependency; import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; import org.apache.maven.project.MavenProject; import org.codehaus.plexus.util.IOUtil; import org.codehaus.plexus.util.StringUtils; import org.hibernate.cfg.AnnotationConfiguration; import org.hibernate.dialect.Dialect; import org.hibernate.tool.hbm2ddl.SchemaExport; import org.scannotation.AnnotationDB; /** * Maven2 plugin to generate SQL DDL scripts out of JPA entities. * * <p> * Test via: * <code>mvn be.fedict.eid-applet:eid-applet-sql-ddl-plugin:1.0.2-SNAPSHOT:generate-sql-ddl</code> * </p> * * @author Frank Cornelis * @goal generate-sql-ddl */ public class SQLDDLMojo extends AbstractMojo { /** * Directory containing the generated docbook XML. * * @parameter expression="${project.build.directory}" * @required */ private File outputDirectory; /** * Name of the generated SQL DDL script. * * @parameter * @required */ private String outputName; /** * Name of the Hibernate dialect to be used for SQL DDL script generation. * * @parameter * @required */ private String hibernateDialect; /** * POM * * @parameter expression="${project}" * @readonly * @required */ protected MavenProject project; /** * @parameter * @required */ private ArrayList<ArtifactItem> artifactItems; /** * Used to look up Artifacts in the remote repository. * * @component */ protected ArtifactFactory artifactFactory; /** * Used to look up Artifacts in the remote repository. * * @component */ protected ArtifactResolver resolver; /** * List of Remote Repositories used by the resolver * * @parameter expression="${project.remoteArtifactRepositories}" * @readonly * @required */ protected java.util.List remoteRepos; /** * Location of the local repository. * * @parameter expression="${localRepository}" * @readonly * @required */ private org.apache.maven.artifact.repository.ArtifactRepository local; @Override public void execute() throws MojoExecutionException, MojoFailureException { getLog().info("SQL DDL script generator"); File outputFile = new File(this.outputDirectory, this.outputName); getLog().info("Output SQL DDL script file: " + outputFile.getAbsolutePath()); this.outputDirectory.mkdirs(); try { outputFile.createNewFile(); } catch (IOException e) { throw new MojoExecutionException("I/O error.", e); } for (ArtifactItem artifactItem : this.artifactItems) { getLog().info("artifact: " + artifactItem.getGroupId() + ":" + artifactItem.getArtifactId()); List<Dependency> dependencies = this.project.getDependencies(); String version = null; for (Dependency dependency : dependencies) { if (StringUtils.equals(dependency.getArtifactId(), artifactItem.getArtifactId()) && StringUtils.equals(dependency.getGroupId(), artifactItem.getGroupId())) { version = dependency.getVersion(); break; } } getLog().info("artifact version: " + version); VersionRange versionRange = VersionRange.createFromVersion(version); Artifact artifact = this.artifactFactory.createDependencyArtifact(artifactItem.getGroupId(), artifactItem.getArtifactId(), versionRange, "jar", null, Artifact.SCOPE_COMPILE); try { this.resolver.resolve(artifact, this.remoteRepos, this.local); } catch (ArtifactResolutionException e) { throw new MojoExecutionException("Unable to resolve artifact.", e); } catch (ArtifactNotFoundException e) { throw new MojoExecutionException("Unable to find artifact.", e); } getLog().info("artifact file: " + artifact.getFile().getAbsolutePath()); getLog().info("hibernate dialect: " + this.hibernateDialect); URL artifactUrl; try { artifactUrl = artifact.getFile().toURI().toURL(); } catch (MalformedURLException e) { throw new MojoExecutionException("URL error.", e); } URLClassLoader classLoader = new URLClassLoader(new URL[] { artifactUrl }, this.getClass().getClassLoader()); Thread.currentThread().setContextClassLoader(classLoader); AnnotationDB annotationDb = new AnnotationDB(); try { annotationDb.scanArchives(artifactUrl); } catch (IOException e) { throw new MojoExecutionException("I/O error.", e); } Set<String> classNames = annotationDb.getAnnotationIndex().get(Entity.class.getName()); getLog().info("# JPA entity classes: " + classNames.size()); AnnotationConfiguration configuration = new AnnotationConfiguration(); configuration.setProperty("hibernate.dialect", this.hibernateDialect); Dialect dialect = Dialect.getDialect(configuration.getProperties()); getLog().info("dialect: " + dialect.toString()); for (String className : classNames) { getLog().info("JPA entity: " + className); Class<?> entityClass; try { entityClass = classLoader.loadClass(className); getLog().info("entity class loader: " + entityClass.getClassLoader()); } catch (ClassNotFoundException e) { throw new MojoExecutionException("class not found.", e); } configuration.addAnnotatedClass(entityClass); } SchemaExport schemaExport = new SchemaExport(configuration); schemaExport.setFormat(true); schemaExport.setHaltOnError(true); schemaExport.setOutputFile(outputFile.getAbsolutePath()); schemaExport.setDelimiter(";"); try { getLog().info("SQL DDL script: " + IOUtil.toString(new FileInputStream(outputFile))); } catch (FileNotFoundException e) { throw new MojoExecutionException("file not found.", e); } catch (IOException e) { throw new MojoExecutionException("I/O error.", e); } // operate schemaExport.execute(true, false, false, true); List<Exception> exceptions = schemaExport.getExceptions(); for (Exception exception : exceptions) { getLog().error("exception: " + exception.getMessage()); } } } }