/** * Copyright 2009 Red Hat, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package org.safehaus.penrose.apacheds; import org.apache.directory.server.core.tools.schema.DirectorySchemaToolMojo; import org.apache.maven.embedder.MavenEmbedder; import org.apache.maven.embedder.MavenEmbedderConsoleLogger; import org.apache.maven.project.MavenProject; import org.apache.log4j.*; import org.apache.log4j.xml.DOMConfigurator; import org.safehaus.penrose.thread.ReaderThread; import java.io.*; import java.util.jar.JarOutputStream; import java.util.jar.Manifest; import java.util.jar.JarEntry; import java.util.*; import java.lang.reflect.Field; import gnu.getopt.LongOpt; import gnu.getopt.Getopt; /** * @author Endi S. Dewata */ public class SchemaGenerator { public static Logger log = Logger.getLogger(SchemaGenerator.class); File schemaDir; String name; File sourceDir; File output; private Collection<String> dependencies; public SchemaGenerator(File file) throws Exception { this.schemaDir = file.getParentFile(); this.name = file.getName(); int i = name.lastIndexOf("."); if (i >= 0) name = name.substring(0, i); sourceDir = File.createTempFile(name, null, schemaDir); sourceDir.delete(); sourceDir.mkdir(); output = new File(schemaDir, name+".jar"); if (output.exists()) output.delete(); } public void run() throws Exception { generate(); compile(); createJar(); delete(); } public void generate() throws Exception { String owner = "uid=admin,ou=system"; String pkg = "org.apache.directory.server.core.schema.bootstrap"; int counter = 0; int size = dependencies == null ? 2 : dependencies.size() + 2; String deps[] = new String[size]; deps[counter++] = "system"; deps[counter++] = "core"; if (dependencies != null) { for (Object dependency : dependencies) { String dep = (String) dependency; deps[counter++] = dep; } } ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); MavenEmbedder maven = new MavenEmbedder(); maven.setClassLoader(classLoader); maven.setLogger(new MavenEmbedderConsoleLogger()); maven.start(); File homeDir = new File(System.getProperty("penrose.home")); File pomFile = new File(homeDir, "pom.xml"); MavenProject pom = maven.readProjectWithDependencies(pomFile); org.apache.directory.server.core.tools.schema.Schema schemas[] = new org.apache.directory.server.core.tools.schema.Schema[1]; schemas[0] = new org.apache.directory.server.core.tools.schema.Schema(); schemas[0].setName(name); schemas[0].setDependencies(deps); schemas[0].setPkg(pkg); schemas[0].setOwner(owner); DirectorySchemaToolMojo tool = new DirectorySchemaToolMojo(); Class clazz = tool.getClass(); Field schemaField = clazz.getDeclaredField("schemas"); schemaField.setAccessible(true); schemaField.set(tool, schemas); Field verboseOutputField = clazz.getDeclaredField("verboseOutput"); verboseOutputField.setAccessible(true); verboseOutputField.setBoolean(tool, true); Field sourceDirectoryField = clazz.getDeclaredField("sourceDirectory"); sourceDirectoryField.setAccessible(true); sourceDirectoryField.set(tool, schemaDir); Field outputDirectoryField = clazz.getDeclaredField("outputDirectory"); outputDirectoryField.setAccessible(true); outputDirectoryField.set(tool, sourceDir); Field defaultPackageField = clazz.getDeclaredField("defaultPackage"); defaultPackageField.setAccessible(true); defaultPackageField.set(tool, pkg); Field defaultOwnerField = clazz.getDeclaredField("defaultOwner"); defaultOwnerField.setAccessible(true); defaultOwnerField.set(tool, owner); Field projectField = clazz.getDeclaredField("project"); projectField.setAccessible(true); projectField.set(tool, pom); tool.execute(); /* EventMonitor eventMonitor = new DefaultEventMonitor( new PlexusLoggerAdapter(new MavenEmbedderConsoleLogger()) ); maven.execute( pom, Collections.singletonList("package"), eventMonitor, new ConsoleDownloadMonitor(), null, targetDirectory ); */ } public void compile() throws Exception { compile(sourceDir); } public void compile(File file) throws Exception { File files[] = file.listFiles(); if (files != null) { for (File f : files) { compile(f); } } if (file.isDirectory()) return; if (!file.getName().endsWith(".java")) return; //String path = file.getPath().substring(prefix.length()+1); //System.out.println("Compiling "+path); String extdirs = ".."+File.separator+"SERVICE-INF"+File.separator+"lib"; String command[] = new String[] { "javac", "-extdirs", extdirs, file.getAbsolutePath() }; for (String s : command) { System.out.print(s + " "); } System.out.println(); Runtime runtime = Runtime.getRuntime(); Process process = runtime.exec(command); new ReaderThread(process.getInputStream(), System.out).start(); new ReaderThread(process.getErrorStream(), System.err).start(); PrintWriter out = new PrintWriter(new OutputStreamWriter(process.getOutputStream()), true); int rc = process.waitFor(); out.close(); if (rc != 0) { System.out.println("Error: rc="+rc); System.exit(rc); } } public void createJar() throws Exception { Manifest manifest = new Manifest(); JarOutputStream os = new JarOutputStream(new FileOutputStream(output), manifest); addJarEntries(sourceDir.getPath(), sourceDir, os); os.close(); } public void addJarEntries(String prefix, File file, JarOutputStream os) throws Exception { File files[] = file.listFiles(); if (files != null) { for (File f : files) { addJarEntries(prefix, f, os); } } if (file.isDirectory()) return; String path = file.getPath().substring(prefix.length()+1); path = path.replace('\\', '/'); if (path.endsWith(".java")) return; //System.out.println("Adding "+path); FileInputStream is = new FileInputStream(file); JarEntry jarEntry = new JarEntry(path); os.putNextEntry(jarEntry); byte[] buf = new byte[4096]; int read; while ((read = is.read(buf)) != -1) { os.write(buf, 0, read); } os.closeEntry(); is.close(); } public void delete() { delete(sourceDir); } public void delete(File file) { File files[] = file.listFiles(); if (files != null) { for (File f : files) { delete(f); } } //String path = file.getPath(); //System.out.println("Deleting "+path); file.delete(); } public static void showUsage() { System.out.println("Usage: org.safehaus.penrose.apacheds.SchemaGenerator [OPTION]... <FILE>"); System.out.println(); System.out.println("Options:"); System.out.println(" -?, --help display this help and exit"); System.out.println(" -n generate source code only"); } public static void main(String args[]) throws Exception { boolean generateOnly = false; StringBuilder depends = new StringBuilder(); LongOpt[] longopts = new LongOpt[1]; longopts[0] = new LongOpt("help", LongOpt.NO_ARGUMENT, null, '?'); Getopt getopt = new Getopt("SchemaGenerator", args, "-:?d:n", longopts); Collection<String> parameters = new ArrayList<String>(); int c; while ((c = getopt.getopt()) != -1) { switch (c) { case ':': case '?': showUsage(); System.exit(0); break; case 1: parameters.add(getopt.getOptarg()); break; case 'd': depends.append(getopt.getOptarg()); break; case 'n': generateOnly = true; break; } } if (parameters.size() == 0) { showUsage(); System.exit(0); } String homeDirectory = System.getProperty("penrose.home"); Logger rootLogger = Logger.getRootLogger(); rootLogger.setLevel(Level.OFF); Logger logger = Logger.getLogger("org.safehaus.penrose"); File log4jProperties = new File((homeDirectory == null ? "" : homeDirectory+File.separator)+"conf"+File.separator+"log4j.properties"); File log4jXml = new File((homeDirectory == null ? "" : homeDirectory+File.separator)+"conf"+File.separator+"log4j.xml"); if (log4jProperties.exists()) { PropertyConfigurator.configure(log4jProperties.getAbsolutePath()); } else if (log4jXml.exists()) { DOMConfigurator.configure(log4jXml.getAbsolutePath()); } else { logger.setLevel(Level.DEBUG); ConsoleAppender appender = new ConsoleAppender(new PatternLayout("%-20C{1} [%4L] %m%n")); BasicConfigurator.configure(appender); } Iterator iterator = parameters.iterator(); String path = (String)iterator.next(); File file = new File(path); file = file.getAbsoluteFile(); SchemaGenerator sg = new SchemaGenerator(file); if (depends.length() > 0) { sg.setDependencies(Arrays.asList(depends.toString().split(" "))); } if (generateOnly) { sg.generate(); } else { sg.run(); } } public Collection getDependencies() { return dependencies; } public void setDependencies(Collection<String> dependencies) { this.dependencies = dependencies; } }