be.fedict.eid.applet.maven.sql.ddl.SQLDDLMojo.java Source code

Java tutorial

Introduction

Here is the source code for be.fedict.eid.applet.maven.sql.ddl.SQLDDLMojo.java

Source

/*
 * 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());
            }
        }
    }
}