All Downloads are FREE. Search and download functionalities are using the official Maven repository.

ru.circumflex.maven.GenerateSchemaMojo Maven / Gradle / Ivy

package ru.circumflex.maven;

import org.apache.commons.io.FilenameUtils;
import ru.circumflex.orm.DDLUnit;
import ru.circumflex.orm.SchemaObject;
import ru.circumflex.orm.FileDeploymentHelper;
import org.apache.maven.plugin.MojoExecutionException;
import java.io.File;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.List;

/**
 * @goal schema
 */
public class GenerateSchemaMojo extends AbstractCircumflexMojo {

    /**
     * @parameter
     */
    private List packages;

    /**
     * @parameter expression="${drop}" default-value="false"
     */
    private boolean drop;

    /**
     * @parameter
     */
    private List deployments;

    /**
     * @parameter expression="${deploymentsSuffix}" default-value=".cxd.xml"
     */
    private String deploymentsSuffix;

    private DDLUnit ddl = new DDLUnit();

    public void execute() throws MojoExecutionException {
        ClassLoader oldCld = Thread.currentThread().getContextClassLoader();
        try {
            URLClassLoader cld = prepareClassLoader();
            Thread.currentThread().setContextClassLoader(cld);
            processSchema();
            processDeployments();
        } catch (Exception e) {
            throw new MojoExecutionException("DDL export failed.", e);
        } finally {
            Thread.currentThread().setContextClassLoader(oldCld);
        }
    }

    private void processSchema() {
        if (packages != null)
            for (String pkg : packages)
                processPackage(pkg);
        if (ddl.schemata().size() > 0) {
            if (drop) ddl.drop();
            ddl.create();
            for (DDLUnit.Msg msg : ddl.msgsArray()) {
                if (msg instanceof DDLUnit.InfoMsg)
                    getLog().info(msg.body());
                else if (msg instanceof DDLUnit.ErrorMsg)
                    getLog().error(msg.body());
                getLog().debug(msg.sql());
            }
        } else {
            getLog().info("No schema objects found to export.");
        }
    }

    private void processPackage(String pkg) {
        String pkgPath = pkg.replaceAll("\\.", "/");
        try {
            URL outputDir = new URL("file://" + project.getBuild().getOutputDirectory() + "/");
            URL pkgUrl = Thread.currentThread().getContextClassLoader().getResource(pkgPath);
            if (pkgUrl != null) {
                File classDir = new File(outputDir.getFile() + pkgPath);
                if (!classDir.exists()) return;
                for (File f : classDir.listFiles()) try {
                    if (f.getName().endsWith(".class")) {
                        String className = pkg + "." +
                                f.getName().substring(0, f.getName().length() - ".class".length());
                        // Let's ensure that anonymous objects are not processed separately.
                        if (!className.matches("[^\\$]+(?:\\$$)?")) continue;
                        Class c = Thread.currentThread()
                                .getContextClassLoader()
                                .loadClass(className);
                        SchemaObject so = null;
                        try {
                            // Try to process it as a singleton.
                            Field module = c.getField("MODULE$");
                            if (isSchemaObjectType(module.getType()))
                                so = (SchemaObject)module.get(null);
                        } catch (NoSuchFieldException e) {
                            // Try to instantiate it as a POJO.
                            if (isSchemaObjectType(c))
                                so = (SchemaObject)c.newInstance();
                        }
                        if (so != null) {   // Found appropriate object.
                            ddl.addObject(so);
                            getLog().debug("Found schema object: " + c.getName());
                        }
                    }
                } catch (Exception e) {
                    getLog().error("Failed to process a file: " + f.getAbsolutePath());
                }
            } else getLog().warn("Omitting non-existent package " + pkgPath);
        } catch (Exception e) {
            getLog().warn("Package processing failed: " + pkgPath, e);
        }
    }

    private boolean isSchemaObjectType(Class c) {
        return SchemaObject.class.isAssignableFrom(c)
                && !Modifier.isAbstract(c.getModifiers())
                && !Modifier.isInterface(c.getModifiers());
    }

    private void processDeployments() {
        if (deployments == null) deployments = new ArrayList();
        deployments.add("default.cxd.xml");
        for (String pkg : packages)
            findDeployments(pkg.replaceAll("\\.", "/"));
        findDeployments("");
        for (String d : deployments)
            processDeployment(d);
    }

    private void findDeployments(String relPath) {
        try {
            String path = project.getBuild().getOutputDirectory() + "/" + relPath;
            File dir = new File(FilenameUtils.separatorsToSystem(path));
            for (File f : dir.listFiles())
                if (f.getName().endsWith(deploymentsSuffix)) {
                    String d = relPath.equals("") ? f.getName() : relPath + "/" + f.getName();
                    if (!deployments.contains(d)) deployments.add(d);
                }
        } catch (Exception e) {
            getLog().warn("Could not process deployments for package " + relPath + ".");
        }
    }

    private void processDeployment(String deployment) {
        String path = project.getBuild().getOutputDirectory() + "/" + deployment;
        File f = new File(FilenameUtils.separatorsToSystem(path));
        if (!f.isFile()) {
            getLog().warn("Omitting non-existent deployment " + deployment + ".");
            return;
        }
        try {
            new FileDeploymentHelper(f).process();
            getLog().info("Deployment " + deployment + " processed successfully.");
        } catch (Exception e) {
            getLog().error("Could not process deployment " + deployment + ".", e);
        }
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy