Author: tchemit Date: 2009-01-02 08:25:38 +0000 (Fri, 02 Jan 2009) New Revision: 1112 Modified: lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/compiler/JAXXCompiler.java lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/compiler/JAXXCompilerLaunchor.java Log: nettoyage code apres refactor + amelioration de la compile -utilisation d'une enum pour definir la phase en cours Modified: lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/compiler/JAXXCompiler.java =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/compiler/JAXXCompiler.java 2009-01-02 08:23:35 UTC (rev 1111) +++ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/compiler/JAXXCompiler.java 2009-01-02 08:25:38 UTC (rev 1112) @@ -69,7 +69,7 @@ /** * Compiles JAXX files into Java classes. - * <p/> + * <p/> * use {@link Generator} ... todo finish javadoc */ public class JAXXCompiler { @@ -1090,7 +1090,7 @@ assert jaxxFile.getName().equalsIgnoreCase(className.substring(className.lastIndexOf(".") + 1) + ".jaxx") : "expecting file name to match " + className + ", but found " + jaxxFile.getName(); if (jaxxFile.getName().equals(className.substring(className.lastIndexOf(".") + 1) + ".jaxx")) { // check case match - if (JAXXCompilerLaunchor.get().currentPass == JAXXCompilerLaunchor.PASS_2) { + if (JAXXCompilerLaunchor.get().currentPass != JAXXCompilerLaunchor.LifeCycle.compile_first_pass) { throw new AssertionError("Internal error: adding dependency class " + className + " during second compilation pass"); } JAXXCompilerLaunchor.get().jaxxFileClassNames.add(className); @@ -1319,170 +1319,6 @@ return System.getProperty("line.separator", "\n"); } - /** - * Compiled a set of files, with the class names specified explicitly. The class compiled from files[i] will be named classNames[i]. - * Returns <code>true</code> if compilation succeeds, <code>false</code> if it fails. Warning and error messages are sent to - * <code>System.err</code>. - * - * @param files the .jaxx files to compile - * @param classNames the names of the classes being compiled - * @param options the compiler options to use - * @return <code>true</code> if compilation succeeds, <code>false</code> otherwise - */ - /*public static synchronized boolean compile(File[] files, String[] classNames, CompilerOptions options) { - reset(); // just to be safe... - jaxxFiles.addAll(Arrays.asList(files)); - jaxxFileClassNames.addAll(Arrays.asList(classNames)); - try { - boolean success = true; - - // pass 1 - currentPass = PASS_1; - boolean compiled; - do { - compiled = false; - assert jaxxFiles.size() == jaxxFileClassNames.size(); - java.util.Iterator<File> filesIterator = new ArrayList<File>(jaxxFiles).iterator(); // clone it so it can safely be modified while we're iterating - java.util.Iterator<String> classNamesIterator = new ArrayList<String>(jaxxFileClassNames).iterator(); - while (filesIterator.hasNext()) { - File file = filesIterator.next(); - String className = classNamesIterator.next(); - if (options.isVerbose()) { - log.info("compile first pass for " + className); - } - if (symbolTables.get(file) == null) { - compiled = true; - if (compilers.containsKey(className)) { - throw new CompilerException("Internal error: " + className + " is already being compiled, attempting to compile it again"); - } - - File destDir = options.getTargetDirectory(); - if (destDir != null) { - int dotPos = className.lastIndexOf("."); - if (dotPos != -1) { - destDir = new File(destDir, className.substring(0, dotPos).replace('.', File.separatorChar)); - } - if (!destDir.exists() && !destDir.mkdirs()) { - log.warn("could not create directory " + destDir); - continue; - } - } else { - //destDir = file.getParentFile(); - } - Compiler compiler = new JAXXCompiler(file.getParentFile(), file, className, options); - compilers.put(className, compiler); - compiler.compileFirstPass(); - assert !symbolTables.values().contains(compiler.getSymbolTable()) : "symbolTable is already registered"; - symbolTables.put(file, compiler.getSymbolTable()); - if (compiler.isFailed()) { - success = false; - } - } - } - - } while (compiled); - - // pass 2 - currentPass = PASS_2; - if (success) { - assert jaxxFiles.size() == jaxxFileClassNames.size(); - List<File> jaxxFilesClone = new ArrayList<File>(jaxxFiles); - for (String className : jaxxFileClassNames) { - Compiler compiler = compilers.get(className); - if (compiler == null) { - throw new CompilerException("Internal error: could not find compiler for " + className + " during second pass"); - } - if (options.isVerbose()) { - - log.info("runInitializers for " + className); - } - if (!compiler.isFailed()) { - compiler.runInitializers(); - } - if (options.isVerbose()) { - - log.info("compile second pass for " + className); - } - compiler.compileSecondPass(); - if (options.isVerbose()) { - - log.info("done with result [" + !compiler.isFailed() + "] for " + className); - } - if (!compiler.isFailed()) { - - } else { - success = false; - } - } - if (!jaxxFilesClone.equals(jaxxFiles)) { - throw new AssertionError("Internal error: compilation set altered during pass 2 (was " + jaxxFilesClone + ", modified to " + jaxxFiles + ")"); - } - } - - // stylesheet application - if (success) { - assert jaxxFiles.size() == jaxxFileClassNames.size(); - for (String className : jaxxFileClassNames) { - Compiler compiler = compilers.get(className); - if (compiler == null) { - throw new CompilerException("Internal error: could not find compiler for " + className + " during stylesheet application"); - } - compiler.applyStylesheets(); - if (compiler.isFailed()) { - success = false; - } - } - } - - // code generation - if (success) { - assert jaxxFiles.size() == jaxxFileClassNames.size(); - List<Generator> generators = new ArrayList<Generator>(); - for (Generator generator : ServiceLoader.load(Generator.class)) { - generators.add(generator); - } - for (String className : jaxxFileClassNames) { - Compiler compiler = compilers.get(className); - if (compiler == null) { - throw new CompilerException("Internal error: could not find compiler for " + className + " during code generation"); - } - compiler.generateCode(generators); - //compiler.generateCode(); - if (compiler.isFailed()) { - success = false; - } - } - } - - if (warningCount == 1) { - System.err.println("1 warning"); - } else if (warningCount > 0) { - System.err.println(warningCount + " warnings"); - } - if (errorCount == 1) { - System.err.println("1 error"); - } else if (errorCount > 0) { - System.err.println(errorCount + " errors"); - } - return success; - } - catch (CompilerException e) { - System.err.println(e.getMessage()); - e.printStackTrace(); - return false; - } - catch (Throwable e) { - e.printStackTrace(); - return false; - } - finally { - //TC - 20081018 only reset when no error was detected - if (options.isResetAfterCompile() && errorCount == 0) { - reset(); - } - } - }*/ - // 1.5 adds getCanonicalName; unfortunately we can't depend on 1.5 features yet public static String getCanonicalName(Class clazz) { if (clazz.isArray()) { Modified: lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/compiler/JAXXCompilerLaunchor.java =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/compiler/JAXXCompilerLaunchor.java 2009-01-02 08:23:35 UTC (rev 1111) +++ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/compiler/JAXXCompilerLaunchor.java 2009-01-02 08:25:38 UTC (rev 1112) @@ -1,14 +1,13 @@ package jaxx.compiler; import jaxx.CompilerException; +import jaxx.reflect.ClassDescriptorLoader; import jaxx.spi.Initializer; -import jaxx.reflect.ClassDescriptorLoader; import jaxx.tags.DefaultObjectHandler; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import java.io.File; -import java.io.IOException; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; @@ -21,116 +20,122 @@ /** @author chemit */ public class JAXXCompilerLaunchor { - /** log */ protected static final Log log = LogFactory.getLog(JAXXCompilerLaunchor.class); + enum LifeCycle { + init,// state before compilation + compile_first_pass, // state when first pass of compilation + compile_second_pass, // state when second pass of compilation + stylesheet_pass, // state when applygin stylesheet phase after compilation + generate_pass // state when generation phase + } + protected static final int PASS_1 = 0; protected static final int PASS_2 = 1; + + /** shared instance of unique launchor at a givne time. */ protected static JAXXCompilerLaunchor singleton; - protected CompilerOptions options; - - protected final File[] files; - protected final String[] classNames; - - public JAXXCompilerLaunchor(File base, String[] relativePaths, CompilerOptions options) { - this.options = options; - files = new File[relativePaths.length]; - classNames = new String[relativePaths.length]; - for (int i = 0; i < files.length; i++) { - files[i] = new File(base, relativePaths[i]); - classNames[i] = relativePaths[i].substring(0, relativePaths[i].lastIndexOf(".")); - classNames[i] = classNames[i].replace(File.separatorChar, '.'); - classNames[i] = classNames[i].replace('/', '.'); - classNames[i] = classNames[i].replace('\\', '.'); - classNames[i] = classNames[i].replace(':', '.'); - } - if (options.isVerbose()) { - log.info("files : " + Arrays.toString(files)); - } - } - - public JAXXCompilerLaunchor(File[] files, String[] classNames, CompilerOptions options) { - this.options = options; - this.files = files; - this.classNames = classNames; - if (options.isVerbose()) { - log.info("files : " + Arrays.toString(files)); - } - } - - public JAXXCompilerLaunchor() { - this.options = new CompilerOptions(); - files = null; - classNames = null; - } - /** - * Compiled a set of files, expressed as paths relative to a base directory. The class names of the compiled files are derived - * from the relative path strings (e.g. "example/Foo.jaxx" compiles into a class named "example.Foo"). Returns <code>true</code> - * if compilation succeeds, <code>false</code> if it fails. Warning and error messages are sent to <code>System.err</code>. + * Create a new empty launchor and set it as current launchor accessible via method {@link #get()} * - * @return <code>true</code> if compilation succeeds, <code>false</code> otherwise + * @return the new instanciated launchor */ - public static JAXXCompilerLaunchor newLaunchor() { - if (singleton != null) { - //singleton.reset(); - } - singleton = new JAXXCompilerLaunchor(); - - return singleton; + public static synchronized JAXXCompilerLaunchor newLaunchor() { + return newLaunchor((File[]) null, null, null); } /** - * Compiled a set of files, expressed as paths relative to a base directory. The class names of the compiled files are derived - * from the relative path strings (e.g. "example/Foo.jaxx" compiles into a class named "example.Foo"). Returns <code>true</code> - * if compilation succeeds, <code>false</code> if it fails. Warning and error messages are sent to <code>System.err</code>. + * Create a new launchor and set it as current launchor accessible via method {@link #get()}. + * <p/> + * The launchor will be prepared to compile a set of files, expressed as paths relative to a base directory. + * The class names of the compiled files are derived from the relative path strings + * (e.g. "example/Foo.jaxx" compiles into a class named "example.Foo"). * * @param base the directory against which to resolve relative paths * @param relativePaths a list of relative paths to .jaxx files being compiled * @param options the compiler options to use - * @return <code>true</code> if compilation succeeds, <code>false</code> otherwise + * @return the new instanciated launchor */ - public static JAXXCompilerLaunchor newLaunchor(File base, String[] relativePaths, CompilerOptions options) { - if (singleton != null) { - //singleton.reset(); + public static synchronized JAXXCompilerLaunchor newLaunchor(File base, String[] relativePaths, CompilerOptions options) { + File[] files = new File[relativePaths.length]; + String[] classNames = new String[relativePaths.length]; + for (int i = 0; i < files.length; i++) { + files[i] = new File(base, relativePaths[i]); + classNames[i] = relativePaths[i].substring(0, relativePaths[i].lastIndexOf(".")); + classNames[i] = classNames[i].replace(File.separatorChar, '.'); + classNames[i] = classNames[i].replace('/', '.'); + classNames[i] = classNames[i].replace('\\', '.'); + classNames[i] = classNames[i].replace(':', '.'); } - singleton = new JAXXCompilerLaunchor(base, relativePaths, options); - - return singleton; + return newLaunchor(files, classNames, options); } /** - * Compiled a set of files, with the class names specified explicitly. The class compiled from files[i] will be named classNames[i]. - * Returns <code>true</code> if compilation succeeds, <code>false</code> if it fails. Warning and error messages are sent to - * <code>System.err</code>. + * Create a new launchor and set it as current launchor accessible via method {@link #get()}. + * <p/> + * The launchor will be prepared to compile a set of files, with the class names specified explicitly. + * The class compiled from files[i] will be named classNames[i]. * * @param files the .jaxx files to compile * @param classNames the names of the classes being compiled * @param options the compiler options to use - * @return <code>true</code> if compilation succeeds, <code>false</code> otherwise + * @return the new instanciated launchor */ - public static JAXXCompilerLaunchor newLaunchor(File[] files, String[] classNames, CompilerOptions options) { + public static synchronized JAXXCompilerLaunchor newLaunchor(File[] files, String[] classNames, CompilerOptions options) { if (singleton != null) { - //singleton.reset(); + singleton.reset(); } singleton = new JAXXCompilerLaunchor(files, classNames, options); return singleton; } - public static JAXXCompilerLaunchor get() { + /** + * @return the current launchor + * @throws NullPointerException if no launchor was registred via a <code>newLaunchor-like</code> method. + */ + public static JAXXCompilerLaunchor get() throws NullPointerException { if (singleton == null) { throw new NullPointerException("no launchor was registred via newLaunchor method"); } return singleton; } + /** @return <code> if there is a launchor registred, <code>false</code> otherwise. */ public static boolean isRegistred() { return singleton != null; } + /** + * Load the {@link jaxx.spi.Initializer} services found via the{@link ServiceLoader} mecanism. + * + * @param verbose <ocde>true</code> to print initializers + */ + public static void loadLibraries(boolean verbose) { + //BeanInfoUtil.reset(); + ClassLoader classloader = Thread.currentThread().getContextClassLoader(); + if (verbose) { + log.info("with cl " + classloader); + } + ServiceLoader<Initializer> loader = ServiceLoader.load(Initializer.class, classloader); + for (Initializer initializer : loader) { + if (verbose) { + log.info("load initializer " + initializer); + } + initializer.initialize(); + } + } + + /** options of the launchor and underlines compilers */ + protected CompilerOptions options; + /** original list of files to compile */ + protected final File[] files; + /** original list of classes to compile */ + protected final String[] classNames; + + /** Files to be treated while compilation. */ protected List<File> jaxxFiles = new ArrayList<File>(); /** Class names corresponding to the files in the jaxxFiles list. */ @@ -142,26 +147,22 @@ /** Maps the names of classes being compiled to their symbol tables (created after the first compiler pass). */ protected Map<File, SymbolTable> symbolTables = new HashMap<File, SymbolTable>(); - protected int currentPass; + protected LifeCycle currentPass; + //protected int currentPass; protected int errorCount; protected int warningCount; - public static void loadLibraries(boolean verbose) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException { - //BeanInfoUtil.reset(); - ClassLoader classloader = Thread.currentThread().getContextClassLoader(); - if (verbose) { - log.info("with cl " + classloader); + protected JAXXCompilerLaunchor(File[] files, String[] classNames, CompilerOptions options) { + this.options = options == null ? new CompilerOptions() : options; + this.files = files; + this.classNames = classNames; + if (this.options.isVerbose()) { + log.info("files : " + Arrays.toString(files)); } - ServiceLoader<Initializer> loader = ServiceLoader.load(Initializer.class, classloader); - for (Initializer initializer : loader) { - if (verbose) { - log.info("load initializer " + initializer); - } - initializer.initialize(); - } } + public void init() { // forces static initializer to run if it hasn't yet } @@ -175,6 +176,7 @@ symbolTables.clear(); compilers.clear(); } + public String getVersion() { return "1.0.4"; } @@ -243,7 +245,7 @@ boolean success = true; // pass 1 - currentPass = PASS_1; + currentPass = LifeCycle.compile_first_pass; boolean compiled; do { compiled = false; @@ -287,90 +289,84 @@ } } while (compiled); + if (!success) { + return report(false); + } // pass 2 - currentPass = PASS_2; - if (success) { - assert jaxxFiles.size() == jaxxFileClassNames.size(); - List<File> jaxxFilesClone = new ArrayList<File>(jaxxFiles); - for (String className : jaxxFileClassNames) { - JAXXCompiler compiler = compilers.get(className); - if (compiler == null) { - throw new CompilerException("Internal error: could not find compiler for " + className + " during second pass"); - } - if (options.isVerbose()) { + currentPass = LifeCycle.compile_second_pass; - log.info("runInitializers for " + className); - } - if (!compiler.isFailed()) { - compiler.runInitializers(); - } - if (options.isVerbose()) { + assert jaxxFiles.size() == jaxxFileClassNames.size(); + List<File> jaxxFilesClone = new ArrayList<File>(jaxxFiles); + for (String className : jaxxFileClassNames) { + JAXXCompiler compiler = compilers.get(className); + if (compiler == null) { + throw new CompilerException("Internal error: could not find compiler for " + className + " during second pass"); + } + if (options.isVerbose()) { - log.info("compile second pass for " + className); - } - compiler.compileSecondPass(); - if (options.isVerbose()) { + log.info("runInitializers for " + className); + } + if (!compiler.isFailed()) { + compiler.runInitializers(); + } + if (options.isVerbose()) { - log.info("done with result [" + !compiler.isFailed() + "] for " + className); - } - if (!compiler.isFailed()) { - - } else { - success = false; - } + log.info("compile second pass for " + className); } - if (!jaxxFilesClone.equals(jaxxFiles)) { - throw new AssertionError("Internal error: compilation set altered during pass 2 (was " + jaxxFilesClone + ", modified to " + jaxxFiles + ")"); + compiler.compileSecondPass(); + if (options.isVerbose()) { + log.info("done with result [" + !compiler.isFailed() + "] for " + className); } + if (compiler.isFailed()) { + success = false; + } } + if (!jaxxFilesClone.equals(jaxxFiles)) { + throw new AssertionError("Internal error: compilation set altered during pass 2 (was " + jaxxFilesClone + ", modified to " + jaxxFiles + ")"); + } + if (!success) { + return report(false); + } + // stylesheet application - if (success) { - assert jaxxFiles.size() == jaxxFileClassNames.size(); - for (String className : jaxxFileClassNames) { - JAXXCompiler compiler = compilers.get(className); - if (compiler == null) { - throw new CompilerException("Internal error: could not find compiler for " + className + " during stylesheet application"); - } - compiler.applyStylesheets(); - if (compiler.isFailed()) { - success = false; - } + currentPass = LifeCycle.stylesheet_pass; + assert jaxxFiles.size() == jaxxFileClassNames.size(); + for (String className : jaxxFileClassNames) { + JAXXCompiler compiler = compilers.get(className); + if (compiler == null) { + throw new CompilerException("Internal error: could not find compiler for " + className + " during stylesheet application"); } + compiler.applyStylesheets(); + if (compiler.isFailed()) { + success = false; + } } + if (!success) { + return report(false); + } // code generation - if (success) { - assert jaxxFiles.size() == jaxxFileClassNames.size(); - List<Generator> generators = new ArrayList<Generator>(); - for (Generator generator : ServiceLoader.load(Generator.class)) { - generators.add(generator); + currentPass = LifeCycle.generate_pass; + assert jaxxFiles.size() == jaxxFileClassNames.size(); + List<Generator> generators = new ArrayList<Generator>(); + for (Generator generator : ServiceLoader.load(Generator.class)) { + generators.add(generator); + } + for (String className : jaxxFileClassNames) { + JAXXCompiler compiler = compilers.get(className); + if (compiler == null) { + throw new CompilerException("Internal error: could not find compiler for " + className + " during code generation"); } - for (String className : jaxxFileClassNames) { - JAXXCompiler compiler = compilers.get(className); - if (compiler == null) { - throw new CompilerException("Internal error: could not find compiler for " + className + " during code generation"); - } - compiler.generateCode(generators); - //compiler.generateCode(); - if (compiler.isFailed()) { - success = false; - } + compiler.generateCode(generators); + //compiler.generateCode(); + if (compiler.isFailed()) { + success = false; } } - if (warningCount == 1) { - System.err.println("1 warning"); - } else if (warningCount > 0) { - System.err.println(warningCount + " warnings"); - } - if (errorCount == 1) { - System.err.println("1 error"); - } else if (errorCount > 0) { - System.err.println(errorCount + " errors"); - } - return success; + return report(success); } catch (CompilerException e) { System.err.println(e.getMessage()); @@ -389,6 +385,20 @@ } } + protected boolean report(boolean success) { + if (warningCount == 1) { + System.err.println("1 warning"); + } else if (warningCount > 0) { + System.err.println(warningCount + " warnings"); + } + if (errorCount == 1) { + System.err.println("1 error"); + } else if (errorCount > 0) { + System.err.println(errorCount + " errors"); + } + return success; + } + protected JAXXCompiler newCompiler(File parentFile, File file, String className) throws InvocationTargetException, IllegalAccessException, InstantiationException, NoSuchMethodException { Constructor<? extends JAXXCompiler> cons = options.getCompilerClass().getConstructor(File.class, File.class, String.class, CompilerOptions.class); return cons.newInstance(parentFile, file, className, options);