/* * Copyright (c) 2016 OBiBa. All rights reserved. * * This program and the accompanying materials * are made available under the terms of the GNU Public License v3.0. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.obiba.core.service.impl.hibernate.ddl; import java.util.Properties; import javax.annotation.Nonnull; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; import org.hibernate.cfg.ImprovedNamingStrategy; import org.hibernate.tool.hbm2ddl.SchemaExport; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @SuppressWarnings("UnusedDeclaration") public class DDLGenerator { static private final Logger log = LoggerFactory.getLogger(DDLGenerator.class); // System constants for the current platform directory token static final String FILE_SEP = System.getProperty("file.separator"); public static final String DEFAULT_DIALECT = "org.hibernate.dialect.MySQLInnoDBDialect"; private SessionFactory sessionFactory; public void setSessionFactory(SessionFactory sessionFactory) { this.sessionFactory = sessionFactory; } /** * Generate DDL scripts in default dialect. */ public void generate() { generate(null, null, getConfiguration(DEFAULT_DIALECT)); } /** * Generate DDL script in given dialect. * * @param path where to write file * @param suffix DDL script file suffix * @param dialect */ public void generate(String path, String suffix, String dialect) { generate(path, suffix, getConfiguration(dialect)); } private Configuration getConfiguration(String dialect) { log.warn("Creating Hibernate Configuration from Session..."); Configuration annoteConf = new Configuration(); for(Object metaKey : sessionFactory.getAllClassMetadata().keySet()) { log.info("annotatedClass={}", metaKey); try { annoteConf.addAnnotatedClass(Class.forName((String) metaKey)); } catch(Exception e) { log.error("Failed adding annotated class.", e); return null; } } annoteConf.setNamingStrategy(ImprovedNamingStrategy.INSTANCE); Properties props = new Properties(); props.put("hibernate.dialect", DEFAULT_DIALECT); annoteConf.addProperties(props); return annoteConf; } /** * Generate DDL script with given configuration. * * @param path where to write file * @param suffix DDL script file suffix * @param conf */ private void generate(String path, String suffix, @Nonnull Configuration conf) { //noinspection ConstantConditions if(conf == null) throw new IllegalArgumentException("Configuration cannot be null."); SchemaExport schemaExport = new SchemaExport(conf); schemaExport.setDelimiter(";"); String safePath = path == null ? "" : path; if(safePath.length() != 0 && !path.endsWith(FILE_SEP)) safePath += FILE_SEP; String safeSuffix = suffix; if(suffix == null || suffix.isEmpty()) { String dialect = conf.getProperty("hibernate.dialect"); safeSuffix = dialect == null ? ".sql" : "_" + dialect.substring(dialect.lastIndexOf('.') + 1) + ".sql"; } schemaExport.setHaltOnError(true); // Despite the name, the generated create // scripts WILL include drop statements at // the top of the script! log.info("CREATE DDL..."); schemaExport.setOutputFile(safePath + "create" + safeSuffix); schemaExport.create(false, false); // Generates DROP statements only log.info("DROP DDL..."); schemaExport.setOutputFile(safePath + "drop" + safeSuffix); schemaExport.drop(false, false); log.error("exceptions: {}", schemaExport.getExceptions().toString()); } }