/*****************************************************************
* 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
*
* http://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.dbsync.reverse.dbimport;
import org.apache.cayenne.CayenneRuntimeException;
import org.apache.cayenne.configuration.DataNodeDescriptor;
import org.apache.cayenne.conn.DataSourceInfo;
import org.apache.cayenne.dba.DbAdapter;
import org.apache.cayenne.dbsync.filter.NameFilter;
import org.apache.cayenne.dbsync.filter.NamePatternMatcher;
import org.apache.cayenne.dbsync.reverse.dbload.DefaultModelMergeDelegate;
import org.apache.cayenne.dbsync.reverse.dbload.ModelMergeDelegate;
import org.apache.cayenne.dbsync.naming.DbEntityNameStemmer;
import org.apache.cayenne.dbsync.naming.DefaultObjectNameGenerator;
import org.apache.cayenne.dbsync.naming.NoStemStemmer;
import org.apache.cayenne.dbsync.naming.ObjectNameGenerator;
import org.apache.cayenne.dbsync.naming.PatternStemmer;
import org.apache.cayenne.dbsync.reverse.dbload.DbLoaderConfiguration;
import org.apache.cayenne.dbsync.reverse.dbload.DbLoaderDelegate;
import org.apache.cayenne.dbsync.reverse.dbload.DefaultDbLoaderDelegate;
import org.apache.cayenne.dbsync.reverse.dbload.LoggingDbLoaderDelegate;
import org.apache.cayenne.dbsync.reverse.filters.FiltersConfig;
import org.slf4j.Logger;
import java.io.File;
import java.util.regex.Pattern;
/**
* @since 4.0
*/
public class DbImportConfiguration {
private static final String DATA_MAP_LOCATION_SUFFIX = ".map.xml";
private final DataSourceInfo dataSourceInfo;
private final DbLoaderConfiguration dbLoaderConfiguration;
private File targetDataMap;
private String defaultPackage;
private String meaningfulPkTables;
private String adapter;
private boolean usePrimitives;
private boolean useJava7Types;
private Logger logger;
private String namingStrategy;
private String stripFromTableNames;
private boolean forceDataMapCatalog;
private boolean forceDataMapSchema;
public DbImportConfiguration() {
this.dataSourceInfo = new DataSourceInfo();
this.dbLoaderConfiguration = new DbLoaderConfiguration();
}
public String getStripFromTableNames() {
return stripFromTableNames;
}
public void setStripFromTableNames(String stripFromTableNames) {
this.stripFromTableNames = stripFromTableNames;
}
public Logger getLogger() {
return logger;
}
public void setLogger(Logger logger) {
this.logger = logger;
}
/**
* Returns DataMap XML file representing the target of the DB import operation.
*/
public File getTargetDataMap() {
return targetDataMap;
}
public void setTargetDataMap(File map) {
this.targetDataMap = map;
}
/**
* Returns a default package for ObjEntity Java classes.
*/
public String getDefaultPackage() {
return defaultPackage;
}
public void setDefaultPackage(String defaultPackage) {
this.defaultPackage = defaultPackage;
}
public String getNamingStrategy() {
return namingStrategy;
}
public void setNamingStrategy(String namingStrategy) {
this.namingStrategy = namingStrategy;
}
/**
* Returns the name of a Java class implementing {@link DbAdapter}. This attribute is optional, the default is
* {@link org.apache.cayenne.dba.AutoAdapter}, i.e. Cayenne will try to guess the DB type.
*/
public String getAdapter() {
return adapter;
}
public void setAdapter(String adapter) {
this.adapter = adapter;
}
/**
* Returns a comma-separated list of Perl5 regular expressions that match
* table names for which {@link DbImportAction} should include ObjAttribute
* for PK.
*/
public String getMeaningfulPkTables() {
return meaningfulPkTables;
}
public void setMeaningfulPkTables(String meaningfulPkTables) {
this.meaningfulPkTables = meaningfulPkTables;
}
public boolean isUsePrimitives() {
return usePrimitives;
}
public void setUsePrimitives(boolean usePrimitives) {
this.usePrimitives = usePrimitives;
}
public boolean isUseJava7Types() {
return useJava7Types;
}
public void setUseJava7Types(boolean useJava7Types) {
this.useJava7Types = useJava7Types;
}
public NameFilter createMeaningfulPKFilter() {
if (meaningfulPkTables == null) {
return NamePatternMatcher.EXCLUDE_ALL;
}
// TODO: this filter can't handle table names with comma in them
String[] patternStrings = meaningfulPkTables.split(",");
Pattern[] patterns = new Pattern[patternStrings.length];
for (int i = 0; i < patterns.length; i++) {
patterns[i] = Pattern.compile(patternStrings[i]);
}
return new NamePatternMatcher(patterns, new Pattern[0]);
}
public ObjectNameGenerator createNameGenerator() {
// TODO: not a singleton; called from different places...
// custom name generator
// TODO: support stemmer in non-standard generators...
// TODO: load via DI AdhocObjectFactory
String namingStrategy = getNamingStrategy();
if (namingStrategy != null && !namingStrategy.equals(DefaultObjectNameGenerator.class.getName())) {
try {
return (ObjectNameGenerator) Class.forName(namingStrategy).newInstance();
} catch (Exception e) {
throw new CayenneRuntimeException("Error creating name generator: " + namingStrategy, e);
}
}
return new DefaultObjectNameGenerator(createStemmer());
}
protected DbEntityNameStemmer createStemmer() {
return (stripFromTableNames == null || stripFromTableNames.length() == 0)
? NoStemStemmer.getInstance()
: new PatternStemmer(stripFromTableNames, false);
}
public String getDriver() {
return dataSourceInfo.getJdbcDriver();
}
public void setDriver(String jdbcDriver) {
dataSourceInfo.setJdbcDriver(jdbcDriver);
}
public String getPassword() {
return dataSourceInfo.getPassword();
}
public void setPassword(String password) {
dataSourceInfo.setPassword(password);
}
public String getUsername() {
return dataSourceInfo.getUserName();
}
public void setUsername(String userName) {
dataSourceInfo.setUserName(userName);
}
public String getUrl() {
return dataSourceInfo.getDataSourceUrl();
}
public void setUrl(String dataSourceUrl) {
dataSourceInfo.setDataSourceUrl(dataSourceUrl);
}
public DataNodeDescriptor createDataNodeDescriptor() {
DataNodeDescriptor nodeDescriptor = new DataNodeDescriptor();
nodeDescriptor.setAdapterType(getAdapter());
nodeDescriptor.setDataSourceDescriptor(dataSourceInfo);
return nodeDescriptor;
}
public String getDataMapName() {
String name = targetDataMap.getName();
if (!name.endsWith(DATA_MAP_LOCATION_SUFFIX)) {
throw new CayenneRuntimeException("DataMap file name must end with '%s': '%s'", DATA_MAP_LOCATION_SUFFIX,
name);
}
return name.substring(0, name.length() - DATA_MAP_LOCATION_SUFFIX.length());
}
public ModelMergeDelegate createMergeDelegate() {
return new DefaultModelMergeDelegate();
}
public DbLoaderDelegate createLoaderDelegate() {
if (getLogger() != null) {
return new LoggingDbLoaderDelegate(getLogger());
} else {
return new DefaultDbLoaderDelegate();
}
}
/**
* Returns configuration that should be used for DB import stage when the schema is loaded from the database.
*/
public DbLoaderConfiguration getDbLoaderConfig() {
return dbLoaderConfiguration;
}
public void setFiltersConfig(FiltersConfig filtersConfig) {
dbLoaderConfiguration.setFiltersConfig(filtersConfig);
}
@Override
public String toString() {
StringBuilder res = new StringBuilder("Importer options:");
for (String line : dbLoaderConfiguration.toString().split("\n")) {
res.append(" ").append(line).append("\n");
}
return res.toString();
}
public DataSourceInfo getDataSourceInfo() {
return dataSourceInfo;
}
public void setSkipRelationshipsLoading(Boolean skipRelationshipsLoading) {
this.dbLoaderConfiguration.setSkipRelationshipsLoading(skipRelationshipsLoading);
}
public void setSkipPrimaryKeyLoading(Boolean skipPrimaryKeyLoading) {
this.dbLoaderConfiguration.setSkipPrimaryKeyLoading(skipPrimaryKeyLoading);
}
public void setTableTypes(String[] tableTypes) {
dbLoaderConfiguration.setTableTypes(tableTypes);
}
public void setForceDataMapCatalog(boolean forceDataMapCatalog) {
this.forceDataMapCatalog = forceDataMapCatalog;
}
public boolean isForceDataMapCatalog() {
return forceDataMapCatalog;
}
public void setForceDataMapSchema(boolean forceDataMapSchema) {
this.forceDataMapSchema = forceDataMapSchema;
}
public boolean isForceDataMapSchema() {
return forceDataMapSchema;
}
}