blob: 487f683ff99c8c4d050818be0fdadda3ecdc5c7c [file] [log] [blame]
package org.apache.juddi.ddl.generator;
/*
* Copyright 2001-2008 The Apache Software Foundation.
*
* Licensed 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.
*/
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.Enumeration;
import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.DefaultParser;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Options;
import static org.apache.http.client.methods.RequestBuilder.options;
import org.hibernate.boot.Metadata;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.tool.hbm2ddl.SchemaExport;
import org.hibernate.tool.hbm2ddl.SchemaExport.Action;
import org.hibernate.tool.schema.TargetType;
/**
* Source:
* http://jandrewthompson.blogspot.com/2009/10/how-to-generate-ddl-scripts-from.html
* https://stackoverflow.com/a/33761464/1203182
* https://stackoverflow.com/a/41894432/1203182
*
* @author john.thompson
* @author Alex O'Ree
*
*/
public class App {
private List<Class> jpaClasses = new ArrayList<>();
public App() {
}
//initial from the current class path
private void initialJpsClassList(String packageName) throws Exception {
List<Class> classesForPackage = getClassesForPackage(Package.getPackage(packageName));
for (Class<Object> clazz : classesForPackage) {
jpaClasses.add(clazz);
}
}
//initialize from a directory /target/classes
private void initialJpsClassList(File dir, String packageName) throws Exception {
List<Class> c = new ArrayList<Class>();
processDirectory(dir, packageName, c);
for (Class<Object> clazz : c) {
jpaClasses.add(clazz);
}
}
/**
* Method that actually creates the file.
*
* @param dbDialect to use
*/
private void generate(org.hibernate.dialect.Dialect dialect, File outputDir) {
StandardServiceRegistryBuilder ssrb = new StandardServiceRegistryBuilder();
ssrb.applySetting("hibernate.dialect", dialect.getClass().getCanonicalName());
StandardServiceRegistry standardServiceRegistry = ssrb.build();
MetadataSources metadataSources = new MetadataSources(standardServiceRegistry);
for (Class clzz : jpaClasses) {
metadataSources.addAnnotatedClass(clzz);
}
Metadata metadata = metadataSources.buildMetadata();
SchemaExport export = new SchemaExport();
export.setDelimiter(";");
export.setOutputFile(outputDir.getAbsolutePath() + File.separator + dialect.getClass().getSimpleName() + ".ddl");
//export.execute(true, false, false, true);
export.execute(EnumSet.of(TargetType.SCRIPT), Action.BOTH, metadata);
}
/**
* @param args
*/
public static void main(String[] args) throws Exception {
Options opts = new Options();
opts.addOption("path", true, "Source path");
opts.addOption("output", true, "Output path");
opts.addOption("package", true, "Class name prefix, defaults to org.apache.juddi.model");
opts.addOption("help", false, "this menu");
CommandLineParser parser = new DefaultParser();
CommandLine cmd = parser.parse(opts, args);
if (cmd.hasOption("help")) {
HelpFormatter formatter = new HelpFormatter();
formatter.printHelp("juddi-ddl-generator", opts);
return;
}
App gen = new App();
String pkg = "org.apache.juddi.model";
if (cmd.hasOption("package")) {
pkg = cmd.getOptionValue("package");
}
File src = new File("../juddi-core/target/classes/org/apache/juddi/model/");
if (cmd.hasOption("path")) {
src = new File(cmd.getOptionValue("path"));
}
File output = new File(".");
if (cmd.hasOption("output")) {
output = new File(cmd.getOptionValue("output"));
}
if (src.exists()) {
gen.initialJpsClassList(src, pkg);
} else {
gen.initialJpsClassList(pkg);
}
Package hibernate = Package.getPackage("org.hibernate.dialect");
if (hibernate == null) {
hibernate = org.hibernate.dialect.DerbyTenSevenDialect.class.getPackage();
}
List<Class> dialetcs = getClassesForPackage(hibernate);
for (Class clz : dialetcs) {
try {
org.hibernate.dialect.Dialect d = (org.hibernate.dialect.Dialect) clz.newInstance();
gen.generate(d, output);
} catch (Throwable t) {
//System.out.println(clz.getCanonicalName() + " failed with " + t.getMessage());
}
}
System.out.println(src + " " + output + " " + pkg);
}
private static void log(String msg) {
System.out.println("ClassDiscovery: " + msg);
}
private static Class<?> loadClass(String className) {
try {
return Class.forName(className);
} catch (ClassNotFoundException e) {
throw new RuntimeException("Unexpected ClassNotFoundException loading class '" + className + "'");
}
}
private static void processDirectory(File directory, String pkgname, List<Class> classes) {
log("Reading Directory '" + directory + "'");
// Get the list of the files contained in the package
if (!directory.exists()) {
return;
}
String[] files = directory.list();
for (int i = 0; i < files.length; i++) {
String fileName = files[i];
String className = null;
// we are only interested in .class files
if (fileName.endsWith(".class")) {
// removes the .class extension
className = pkgname + '.' + fileName.substring(0, fileName.length() - 6);
}
log("FileName '" + fileName + "' => class '" + className + "'");
if (className != null) {
classes.add(loadClass(className));
}
File subdir = new File(directory, fileName);
if (subdir.isDirectory()) {
processDirectory(subdir, pkgname + '.' + fileName, classes);
}
}
}
private static void processJarfile(URL resource, String pkgname, List<Class> classes) {
String relPath = pkgname.replace('.', '/');
String resPath = resource.getPath();
String jarPath = resPath.replaceFirst("[.]jar[!].*", ".jar").replaceFirst("file:", "");
log("Reading JAR file: '" + jarPath + "'");
JarFile jarFile;
try {
jarFile = new JarFile(jarPath);
} catch (IOException e) {
throw new RuntimeException("Unexpected IOException reading JAR File '" + jarPath + "'", e);
}
Enumeration<JarEntry> entries = jarFile.entries();
while (entries.hasMoreElements()) {
JarEntry entry = entries.nextElement();
String entryName = entry.getName();
String className = null;
if (entryName.endsWith(".class") && entryName.startsWith(relPath) && entryName.length() > (relPath.length() + "/".length())) {
className = entryName.replace('/', '.').replace('\\', '.').replace(".class", "");
}
log("JarEntry '" + entryName + "' => class '" + className + "'");
if (className != null) {
classes.add(loadClass(className));
}
}
}
public static List<Class> getClassesForPackage(Package pkg) {
List<Class> classes = new ArrayList<Class>();
String pkgname = pkg.getName();
log(pkgname);
log(pkg.getName());
String relPath = pkgname.replace('.', '/');
// Get a File object for the package
URL resource = ClassLoader.getSystemClassLoader().getResource(relPath);
if (resource == null) {
resource = Thread.currentThread().getContextClassLoader().getResource(relPath);
}
if (resource == null) {
resource = App.class.getClassLoader().getResource(relPath);
}
if (resource == null) {
File s = new File(pkgname);
if (s.exists()) {
processDirectory(s, pkgname, classes);
}
throw new RuntimeException("Unexpected problem: No resource for " + relPath);
}
log("Package: '" + pkgname + "' becomes Resource: '" + resource.toString() + "'");
resource.getPath();
if (resource.toString().startsWith("jar:")) {
processJarfile(resource, pkgname, classes);
} else {
processDirectory(new File(resource.getPath()), pkgname, classes);
}
return classes;
}
/**
* Utility method used to fetch Class list based on a package name.
*
* @param packageName (should be the package containing your annotated
* beans.
*/
private List<Class> getClasses(String packageName) throws Exception {
List classes = new ArrayList();
File directory = null;
ClassLoader cld = Thread.currentThread().getContextClassLoader();
cld = org.apache.juddi.model.Address.class.getClassLoader();
if (cld == null) {
throw new ClassNotFoundException("Can't get class loader.");
}
String path = packageName.replace('.', '/');
//file:/C:/juddi/trunk/juddi-core/target/classes/org/apache/juddi/model
System.out.println(path);
Enumeration resources = cld.getResources(path);
while (resources.hasMoreElements()) {
URL resource = (URL) resources.nextElement();
System.out.println(resource.toExternalForm());
try {
directory = new File(resource.toURI().getPath());
} 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.forName(packageName + '.'
+ files[i].substring(0, files[i].length() - 6)));
}
}
}
}
if (classes.isEmpty()) {
System.err.println("No classes could be loaded.");
System.exit(1);
}
return classes;
}
}