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

org.apache.cayenne.tools.DbImporterMojo Maven / Gradle / Ivy

There is a newer version: 5.0-M1
Show newest version
/*****************************************************************
 *   Licensed to the Apache Software Foundation (ASF) under one
 *  or more contributor license agreements.  See the NOTICE file
 *  distributed with this work for additional information
 *  regarding copyright ownership.  The ASF licenses this file
 *  to you under the Apache License, Version 2.0 (the
 *  "License"); you may not use this file except in compliance
 *  with the License.  You may obtain a copy of the License at
 *
 *    https://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing,
 *  software distributed under the License is distributed on an
 *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 *  KIND, either express or implied.  See the License for the
 *  specific language governing permissions and limitations
 *  under the License.
 ****************************************************************/
package org.apache.cayenne.tools;

import javax.sql.DataSource;
import java.io.File;

import org.apache.cayenne.configuration.DataNodeDescriptor;
import org.apache.cayenne.configuration.server.DataSourceFactory;
import org.apache.cayenne.configuration.server.DbAdapterFactory;
import org.apache.cayenne.dba.DbAdapter;
import org.apache.cayenne.dbsync.DbSyncModule;
import org.apache.cayenne.dbsync.reverse.configuration.ToolsModule;
import org.apache.cayenne.dbsync.reverse.dbimport.DbImportAction;
import org.apache.cayenne.dbsync.reverse.dbimport.DbImportConfiguration;
import org.apache.cayenne.dbsync.reverse.dbimport.DbImportConfigurationValidator;
import org.apache.cayenne.dbsync.reverse.dbimport.DbImportModule;
import org.apache.cayenne.dbsync.reverse.dbimport.ReverseEngineering;
import org.apache.cayenne.dbsync.reverse.filters.FiltersConfigBuilder;
import org.apache.cayenne.di.ClassLoaderManager;
import org.apache.cayenne.di.DIBootstrap;
import org.apache.cayenne.di.Injector;
import org.apache.cayenne.util.Util;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.plugins.annotations.ResolutionScope;
import org.apache.maven.project.MavenProject;
import org.slf4j.Logger;

/**
 * Maven mojo to reverse engineer datamap from DB.
 *
 * @since 3.0
 */
@Mojo(name = "cdbimport", defaultPhase = LifecyclePhase.GENERATE_SOURCES, requiresDependencyResolution = ResolutionScope.COMPILE)
public class DbImporterMojo extends AbstractMojo {

    /**
     * Java class implementing org.apache.cayenne.dba.DbAdapter. This attribute
     * is optional, the default is AutoAdapter, i.e. Cayenne would try to guess
     * the DB type.
     */
    @Parameter(defaultValue = "org.apache.cayenne.dba.AutoAdapter")
    private String adapter;

    /**
     * Connection properties.
     *
     * @see DbImportDataSourceConfig
     * @since 4.0
     */
    @Parameter
    private DbImportDataSourceConfig dataSource = new DbImportDataSourceConfig();

    /**
     * DataMap XML file to use as a base for DB importing.
     */
    @Parameter(required = true)
    private File map;

    /**
     * Project XML file to use. If set cayenneProject will be created or updated after DB importing.
     * This is optional parameter.
     * @since 4.1
     */
    @Parameter
    private File cayenneProject;

    /**
     * An object that contains reverse engineering rules.
     */
    @Parameter(name = "dbimport", property = "dbimport", alias = "dbImport")
    private ReverseEngineering dbImportConfig = new ReverseEngineering();

    @Parameter(defaultValue = "${project}" )
    private MavenProject project;

    public void execute() throws MojoExecutionException, MojoFailureException {

        final Logger logger = new MavenLogger(this);

        if (project == null) {
            throw new MojoExecutionException("Can't load MavenProject.");
        }

        // check missing data source parameters
        dataSource.validate();
        final Injector injector = DIBootstrap.createInjector(
                new DbSyncModule(), new ToolsModule(logger), new DbImportModule(),
                binder -> binder.bind(ClassLoaderManager.class).toInstance(new MavenPluginClassLoaderManager(project)));

        final DbImportConfiguration config = createConfig(logger);

        DataSourceFactory dataSourceFactory = injector.getInstance(DataSourceFactory.class);
        DbAdapterFactory dbAdapterFactory = injector.getInstance(DbAdapterFactory.class);
        DataNodeDescriptor dataNodeDescriptor = config.createDataNodeDescriptor();
        try {
            DataSource dataSource = dataSourceFactory.getDataSource(dataNodeDescriptor);
            DbAdapter dbAdapter = dbAdapterFactory.createAdapter(dataNodeDescriptor, dataSource);
            config.setFiltersConfig(new FiltersConfigBuilder(dbImportConfig)
                    .dataSource(dataSource)
                    .dbAdapter(dbAdapter)
                    .build());
        } catch (Exception e) {
            throw new MojoExecutionException("Error getting dataSource", e);
        }

        final DbImportConfigurationValidator validator = new DbImportConfigurationValidator(
                dbImportConfig, config, injector);

        // TODO: "validator.validate()" creates an AutoAdapter (which checks for DB type), then  "DbImportAction.execute()"
        //   does it again. We need to make AutoAdapter a DI singleton to avoid this extra operation

        try {
            validator.validate();
        } catch (Exception ex) {
            throw new MojoExecutionException(ex.getMessage(), ex);
        }

        try {
            injector.getInstance(DbImportAction.class).execute(config);
        } catch (Exception ex) {
           final Throwable th = Util.unwindException(ex);

            String message = "Error importing database schema";

            if (th.getLocalizedMessage() != null) {
                message += ": " + th.getLocalizedMessage();
            }

            getLog().error(message);
            throw new MojoExecutionException(message, th);
        }
    }

    DbImportConfiguration createConfig(final Logger logger) {

        DbImportConfiguration config = new DbImportConfiguration();
        if (dbImportConfig.getCatalogs().size() == 0 && dbImportConfig.isEmptyContainer()) {
            config.setUseDataMapReverseEngineering(true);
        }
        config.setAdapter(adapter);
        config.setDefaultPackage(dbImportConfig.getDefaultPackage());
        config.setDriver(dataSource.getDriver());
        config.setForceDataMapCatalog(dbImportConfig.isForceDataMapCatalog());
        config.setForceDataMapSchema(dbImportConfig.isForceDataMapSchema());
        config.setLogger(logger);
        config.setMeaningfulPkTables(dbImportConfig.getMeaningfulPkTables());
        config.setNamingStrategy(dbImportConfig.getNamingStrategy());
        config.setPassword(dataSource.getPassword());
        config.setSkipRelationshipsLoading(dbImportConfig.getSkipRelationshipsLoading());
        config.setSkipPrimaryKeyLoading(dbImportConfig.getSkipPrimaryKeyLoading());
        config.setStripFromTableNames(dbImportConfig.getStripFromTableNames());
        config.setTableTypes(dbImportConfig.getTableTypes());
        config.setTargetDataMap(map);
        config.setCayenneProject(cayenneProject);
        config.setUrl(dataSource.getUrl());
        config.setUsername(dataSource.getUsername());
        config.setUsePrimitives(dbImportConfig.isUsePrimitives());
        config.setUseJava7Types(dbImportConfig.isUseJava7Types());

        return config;
    }

    public File getMap() {
        return map;
    }

    /**
     * Used only in tests, Maven will inject value directly into the "map" field
     */
    public void setMap(final File map) {
        this.map = map;
    }

    /**
     * This setter is used by Maven when defined {@code } tag
     */
    public void setDbimport(final ReverseEngineering dbImportConfig) {
        this.dbImportConfig = dbImportConfig;
    }

    /**
     * This setter is used by Maven {@code } tag
     */
    public void setDbImport(final ReverseEngineering dbImportConfig) {
        this.dbImportConfig = dbImportConfig;
    }

    public ReverseEngineering getReverseEngineering() {
        return dbImportConfig;
    }

    public DbImportDataSourceConfig getDataSource() {
        return dataSource;
    }
}






© 2015 - 2024 Weber Informatics LLC | Privacy Policy