package net.etalia.crepuscolo.test.db;

import java.io.File;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

import org.hibernate.cfg.Configuration;
import org.hibernate.tool.hbm2ddl.SchemaExport;

public class SchemaGenerator {

	private Configuration cfg;

	public static void main(String[] args) throws Exception {
		SchemaGenerator gen = new SchemaGenerator("net.etalia.crepuscolo.domain");
		gen.generate(Dialect.MYSQL5);
	}

	public SchemaGenerator(String packageName) throws Exception {
		cfg = new Configuration();
		cfg.setProperty("hibernate.hbm2ddl.auto", "create");
		for (Class<Object> clazz : getClasses(packageName)) {
			cfg.addAnnotatedClass(clazz);
		}
	}

	/**
	 * Method that actually creates the file.
	 * 
	 * @param dbDialect to use
	 */
	protected void generate(Dialect dialect) {
		cfg.setProperty("hibernate.dialect", dialect.getDialectClass());
		SchemaExport export = new SchemaExport(cfg);
		export.setDelimiter(";");
		export.setOutputFile("ddl_" + dialect.name().toLowerCase() + ".sql");
		export.execute(true, false, false, false);
	}

	/**
	 * Utility method used to fetch Class list based on a package name.
	 * 
	 * @param packageName
	 *            (should be the package containing your annotated beans.
	 */
	@SuppressWarnings("unchecked")
	private List<Class<Object>> getClasses(String packageName) throws Exception {
		List<Class<Object>> classes = new ArrayList<Class<Object>>();
		File directory = null;
		try {
			ClassLoader cld = Thread.currentThread().getContextClassLoader();
			if (cld == null) {
				throw new ClassNotFoundException("Can't get class loader.");
			}
			String path = packageName.replace('.', '/');
			URL resource = cld.getResource(path);
			if (resource == null) {
				throw new ClassNotFoundException("No resource for " + path);
			}
			directory = new File(resource.getFile());
		} catch (NullPointerException x) {
			throw new ClassNotFoundException(packageName + " (" + directory
					+ ") does not appear to be a valid package");
		}
		if (directory.exists()) {
			String[] files = directory.list();
			for (int i = 0; i < files.length; i++) {
				if (files[i].endsWith(".class")) {
					// removes the .class extension
					classes.add((Class<Object>) Class.forName(packageName + '.'
							+ files[i].substring(0, files[i].length() - 6)));
				}
			}
		} else {
			throw new ClassNotFoundException(packageName
					+ " is not a valid package");
		}

		return classes;
	}

	/**
	 * Holds the classnames of hibernate dialects for easy reference.
	 */
	protected static enum Dialect {
		MYSQL5("org.hibernate.dialect.MySQL5InnoDBDialect"),
		HSQL("org.hibernate.dialect.HSQLDialect");
		private String dialectClass;
		private Dialect(String dialectClass) {
			this.dialectClass = dialectClass;
		}
		public String getDialectClass() {
			return dialectClass;
		}
	}

}

@@ -220,70 +220,23 @@
 t;%0A%0A
-public class SchemaGenerator %7B%0A%0A%09private Configuration cfg;%0A%0A%09
+/**%0A * use:%0A * 
 publ
@@ -289,18 +289,21 @@
 ption %7B%0A
-%09%09
+ *   
 SchemaGe
@@ -373,42 +373,195 @@
 %22);%0A
-%09%09gen.generate(Dialect.MYSQL5);%0A%09%7D
+ *   gen.setPath(%22src/main/sql/%22);%0A *   gen.generate(Dialect.MYSQL5);%0A * %7D%0A * @author daniele%0A *%0A */%0Apublic class SchemaGenerator %7B%0A%0A%09private Configuration cfg;%0A%09private String path = %22%22;
 %0A%0A%09p
@@ -798,24 +798,84 @@
 z);%0A%09%09%7D%0A%09%7D%0A%0A
+%09public void setPath(String path) %7B%0A%09%09this.path = path;%0A%09%7D%0A%0A
 %09/**%0A%09 * Met
@@ -950,24 +950,21 @@
 %0A%09 */%0A%09p
-rotected
+ublic
  void ge
@@ -1154,16 +1154,23 @@
 putFile(
+path + 
 %22ddl_%22 +
@@ -2719,16 +2719,13 @@
 /%0A%09p
-rotected
+ublic
  sta
@@ -2743,16 +2743,61 @@
 alect %7B%0A
+%09%09HSQL(%22org.hibernate.dialect.HSQLDialect%22),%0A
 %09%09MYSQL5
@@ -2845,20 +2845,23 @@
 ct%22),%0A%09%09
-H
+MY
 SQL
+57
 (%22org.hi
@@ -2868,36 +2868,45 @@
 bernate.dialect.
-H
+My
 SQL
+57InnoDB
 Dialect%22);%0A%09%09pri

Improve SchemaGenerator for public use