r1865 - in trunk: jaxx-compiler jaxx-compiler/src/main/java/jaxx/compiler jaxx-compiler/src/main/java/jaxx/compiler/decorators jaxx-compiler/src/main/java/jaxx/compiler/finalizers jaxx-compiler/src/main/java/jaxx/compiler/reflect jaxx-compiler/src/main/java/jaxx/compiler/script jaxx-compiler/src/main/java/jaxx/compiler/spi jaxx-compiler/src/main/java/jaxx/compiler/tags jaxx-compiler/src/main/java/jaxx/compiler/tags/validator jaxx-compiler/src/main/java/jaxx/compiler/tasks jaxx-compiler/src/ma
Author: tchemit Date: 2010-05-02 18:55:27 +0200 (Sun, 02 May 2010) New Revision: 1865 Url: http://nuiton.org/repositories/revision/jaxx/1865 Log: Evolution #100: am?\195?\169lioration du design du compilateur Added: trunk/jaxx-compiler/src/main/java/jaxx/compiler/JAXXCompilerFile.java trunk/jaxx-compiler/src/main/java/jaxx/compiler/JAXXFactory.java trunk/jaxx-compiler/src/main/java/jaxx/compiler/tasks/ trunk/jaxx-compiler/src/main/java/jaxx/compiler/tasks/CompileFirstPassTask.java trunk/jaxx-compiler/src/main/java/jaxx/compiler/tasks/CompileSecondPassTask.java trunk/jaxx-compiler/src/main/java/jaxx/compiler/tasks/FinalizeTask.java trunk/jaxx-compiler/src/main/java/jaxx/compiler/tasks/GenerateTask.java trunk/jaxx-compiler/src/main/java/jaxx/compiler/tasks/InitTask.java trunk/jaxx-compiler/src/main/java/jaxx/compiler/tasks/JAXXEngineTask.java trunk/jaxx-compiler/src/main/java/jaxx/compiler/tasks/ProfileTask.java trunk/jaxx-compiler/src/main/java/jaxx/compiler/tasks/StyleSheetTask.java Modified: trunk/jaxx-compiler/pom.xml trunk/jaxx-compiler/src/main/java/jaxx/compiler/CompilerConfiguration.java trunk/jaxx-compiler/src/main/java/jaxx/compiler/DefaultCompilerConfiguration.java trunk/jaxx-compiler/src/main/java/jaxx/compiler/JAXXCompiler.java trunk/jaxx-compiler/src/main/java/jaxx/compiler/JAXXEngine.java trunk/jaxx-compiler/src/main/java/jaxx/compiler/JAXXProfile.java trunk/jaxx-compiler/src/main/java/jaxx/compiler/SymbolTable.java trunk/jaxx-compiler/src/main/java/jaxx/compiler/decorators/BoxedCompiledObjectDecorator.java trunk/jaxx-compiler/src/main/java/jaxx/compiler/decorators/DefaultCompiledObjectDecorator.java trunk/jaxx-compiler/src/main/java/jaxx/compiler/decorators/HelpRootCompiledObjectDecorator.java trunk/jaxx-compiler/src/main/java/jaxx/compiler/finalizers/DefaultFinalizer.java trunk/jaxx-compiler/src/main/java/jaxx/compiler/finalizers/SwingFinalizer.java trunk/jaxx-compiler/src/main/java/jaxx/compiler/finalizers/ValidatorFinalizer.java trunk/jaxx-compiler/src/main/java/jaxx/compiler/reflect/ClassDescriptorLoader.java trunk/jaxx-compiler/src/main/java/jaxx/compiler/reflect/JavaFileParser.java trunk/jaxx-compiler/src/main/java/jaxx/compiler/script/ScriptManager.java trunk/jaxx-compiler/src/main/java/jaxx/compiler/spi/DefaultInitializer.java trunk/jaxx-compiler/src/main/java/jaxx/compiler/tags/TagManager.java trunk/jaxx-compiler/src/main/java/jaxx/compiler/tags/validator/BeanValidatorHandler.java trunk/jaxx-compiler/src/main/java/jaxx/compiler/tools/PrintTagInfo.java trunk/jaxx-compiler/src/test/java/jaxx/compiler/tags/TagManagerTest.java trunk/jaxx-demo/src/site/rst/index.rst trunk/maven-jaxx-plugin/src/main/java/org/nuiton/jaxx/plugin/GenerateMojo.java trunk/maven-jaxx-plugin/src/test/java/org/nuiton/jaxx/plugin/JaxxBaseTest.java trunk/src/site/rst/JAXXFile.rst trunk/src/site/rst/dataBinding.rst trunk/src/site/rst/presentation.rst trunk/src/site/rst/useStylesheets.rst trunk/src/site/rst/useSwingObjects.rst Modified: trunk/jaxx-compiler/pom.xml =================================================================== --- trunk/jaxx-compiler/pom.xml 2010-05-02 11:04:42 UTC (rev 1864) +++ trunk/jaxx-compiler/pom.xml 2010-05-02 16:55:27 UTC (rev 1865) @@ -71,4 +71,55 @@ <!-- ************************************************************* --> <packaging>jar</packaging> + <build> + + <plugins> + <!-- expose new plexus components --> + <plugin> + <groupId>org.codehaus.plexus</groupId> + <artifactId>plexus-component-metadata</artifactId> + <executions> + <execution> + <goals> + <goal>generate-metadata</goal> + </goals> + </execution> + </executions> + </plugin> + </plugins> + </build> + + <profiles> + + <!-- perform only on a release stage when using the maven-release-plugin --> + <profile> + <id>reporting</id> + <activation> + <property> + <name>performRelease</name> + <value>true</value> + </property> + </activation> + + <reporting> + + <plugins> + + <plugin> + <groupId>org.codehaus.plexus</groupId> + <artifactId>plexus-maven-plugin</artifactId> + <version>1.3.8</version> + </plugin> + + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>cobertura-maven-plugin</artifactId> + <version>2.3</version> + </plugin> + + </plugins> + </reporting> + + </profile> + </profiles> </project> Modified: trunk/jaxx-compiler/src/main/java/jaxx/compiler/CompilerConfiguration.java =================================================================== --- trunk/jaxx-compiler/src/main/java/jaxx/compiler/CompilerConfiguration.java 2010-05-02 11:04:42 UTC (rev 1864) +++ trunk/jaxx-compiler/src/main/java/jaxx/compiler/CompilerConfiguration.java 2010-05-02 16:55:27 UTC (rev 1865) @@ -25,9 +25,11 @@ package jaxx.compiler; +import jaxx.compiler.spi.Initializer; import jaxx.runtime.JAXXContext; import java.io.File; +import java.util.Map; /** * Configuration of a compiler task. @@ -125,4 +127,10 @@ /** @return the encoding to use to write files */ String getEncoding(); + + Map<String, CompiledObjectDecorator> getDecorators(); + + Map<String, JAXXCompilerFinalizer> getFinalizers(); + + Map<String, Initializer> getInitializers(); } Modified: trunk/jaxx-compiler/src/main/java/jaxx/compiler/DefaultCompilerConfiguration.java =================================================================== --- trunk/jaxx-compiler/src/main/java/jaxx/compiler/DefaultCompilerConfiguration.java 2010-05-02 11:04:42 UTC (rev 1864) +++ trunk/jaxx-compiler/src/main/java/jaxx/compiler/DefaultCompilerConfiguration.java 2010-05-02 16:55:27 UTC (rev 1865) @@ -25,100 +25,108 @@ package jaxx.compiler; +import jaxx.compiler.spi.Initializer; +import jaxx.runtime.JAXXContext; +import jaxx.runtime.JAXXObject; import org.apache.commons.lang.builder.ToStringBuilder; import org.apache.commons.lang.builder.ToStringStyle; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import javax.swing.UIManager; import java.io.File; -import jaxx.runtime.JAXXContext; +import java.util.Map; +import java.util.ServiceLoader; +import java.util.TreeMap; -/** - * Options of the {@link JAXXCompiler} and {@link JAXXEngine}. - * - */ +/** Options of the {@link JAXXCompiler} and {@link JAXXEngine}. */ public class DefaultCompilerConfiguration implements CompilerConfiguration { - /** - * where to generate - */ + + /** Logger */ + private static final Log log = + LogFactory.getLog(DefaultCompilerConfiguration.class); + + /** where to generate */ private File targetDirectory; - /** - * flag to optimize generated code - */ + + /** flag to optimize generated code */ private boolean optimize; - /** - * verbose flag - */ + + /** verbose flag */ private boolean verbose; - /** - * to do a profile pass after generation - */ + + /** to do a profile pass after generation */ private boolean profile; - /** - * a flag to enable or disable i18n generation - */ + + /** a flag to enable or disable i18n generation */ private boolean i18nable; - /** - * a flag to add or not logger on generated jaxx files - */ + + /** a flag to add or not logger on generated jaxx files */ private boolean addLogger; - /** - * a flag to not reset compiler after a compile - */ + + /** a flag to not reset compiler after a compile */ private boolean resetAfterCompile; + /** - * the name of implementation of {@link jaxx.runtime.JAXXContext} - * to be used on {@link jaxx.runtime.JAXXObject}. + * the name of implementation of {@link JAXXContext} + * to be used on {@link JAXXObject}. */ protected Class<? extends JAXXContext> jaxxContextClass; - /** - * list of fqn of class to import for all generated jaxx files - */ + + /** list of fqn of class to import for all generated jaxx files */ protected String[] extraImports; - /** - * default error ui - */ + + /** default error ui */ private Class<?> defaultErrorUI; - /** - * class loader to use in compiler - */ + + /** class loader to use in compiler */ private ClassLoader classLoader; - /** - * the compiler class to use - */ + + /** the compiler class to use */ private Class<? extends JAXXCompiler> compilerClass; + /** * the validator class to use. * * @since 1.6.0 */ private Class<?> validatorClass; + /** * the default compiled object decorator to use if none specifed via * decorator attribute */ private Class<? extends CompiledObjectDecorator> defaultDecoratorClass; - /** - * a flag to use {@link javax.swing.UIManager} to retreave icons. - */ + + /** a flag to use {@link UIManager} to retreave icons. */ private boolean useUIManagerForIcon; - /** - * a flag to generate javax help for any - */ + + /** a flag to generate javax help for any */ private boolean generateHelp; + /** * Fully qualified name of help broker, can not use a class here * since this class should be in sources (so not yet compiled) */ private String helpBrokerFQN; - /** - * Encoding to use to write files - */ + + /** Encoding to use to write files */ private String encoding; - + private boolean autoImportCss; private boolean autoRecurseInCss; + /** decorators available in engine */ + protected Map<String, CompiledObjectDecorator> decorators; + + /** finalizers available in engine */ + protected Map<String, JAXXCompilerFinalizer> finalizers; + + /** initializes availables */ + protected Map<String, Initializer> initializers; + @Override public File getTargetDirectory() { return targetDirectory; @@ -219,6 +227,75 @@ } @Override + public Map<String, CompiledObjectDecorator> getDecorators() { + if (decorators == null) { + decorators = new TreeMap<String, CompiledObjectDecorator>(); + ClassLoader classloader = + Thread.currentThread().getContextClassLoader(); + if (log.isInfoEnabled()) { + log.info("with cl " + classloader); + } + + // load decorators + ServiceLoader<CompiledObjectDecorator> services = + ServiceLoader.load(CompiledObjectDecorator.class, classloader); + for (CompiledObjectDecorator decorator : services) { + if (log.isInfoEnabled()) { + log.info("detected " + decorator); + } + decorators.put(decorator.getName(), decorator); + } + } + return decorators; + } + + @Override + public Map<String, JAXXCompilerFinalizer> getFinalizers() { + if (finalizers == null) { + finalizers = new TreeMap<String, JAXXCompilerFinalizer>(); + + ClassLoader classloader = + Thread.currentThread().getContextClassLoader(); + if (log.isInfoEnabled()) { + log.info("with cl " + classloader); + } + + ServiceLoader<JAXXCompilerFinalizer> services = + ServiceLoader.load(JAXXCompilerFinalizer.class, classloader); + for (JAXXCompilerFinalizer finalizer : services) { + if (log.isInfoEnabled()) { + log.info("detected " + finalizer); + } + finalizers.put(finalizer.getClass().getName(), finalizer); + } + } + return finalizers; + } + + @Override + public Map<String, Initializer> getInitializers() { + if (initializers == null) { + initializers = new TreeMap<String, Initializer>(); + ClassLoader classloader = + Thread.currentThread().getContextClassLoader(); + if (log.isInfoEnabled()) { + log.info("with cl " + classloader); + } + + ServiceLoader<Initializer> loader = + ServiceLoader.load(Initializer.class, classloader); + + for (Initializer initializer : loader) { + if (log.isInfoEnabled()) { + log.info("detected " + initializer); + } + initializers.put(initializer.getClass().getName(), initializer); + } + } + return initializers; + } + + @Override public boolean isAutoImportCss() { return autoImportCss; } Modified: trunk/jaxx-compiler/src/main/java/jaxx/compiler/JAXXCompiler.java =================================================================== --- trunk/jaxx-compiler/src/main/java/jaxx/compiler/JAXXCompiler.java 2010-05-02 11:04:42 UTC (rev 1864) +++ trunk/jaxx-compiler/src/main/java/jaxx/compiler/JAXXCompiler.java 2010-05-02 16:55:27 UTC (rev 1865) @@ -47,213 +47,227 @@ import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.nuiton.util.FileUtil; import org.w3c.dom.Document; import org.w3c.dom.Element; -import org.xml.sax.*; +import org.xml.sax.Attributes; +import org.xml.sax.InputSource; +import org.xml.sax.Locator; +import org.xml.sax.SAXException; +import org.xml.sax.SAXParseException; import org.xml.sax.helpers.AttributesImpl; import org.xml.sax.helpers.XMLFilterImpl; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; -import javax.xml.transform.*; +import javax.xml.transform.ErrorListener; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerConfigurationException; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMResult; import javax.xml.transform.sax.SAXSource; -import java.io.*; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileWriter; +import java.io.IOException; +import java.io.InputStream; +import java.io.PrintWriter; +import java.io.UnsupportedEncodingException; import java.lang.reflect.Modifier; import java.net.URL; import java.net.URLDecoder; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.Stack; +import java.util.StringTokenizer; /** - * Compiles JAXX files into Java classes. - * <p/> - * use {@link JAXXCompilerFinalizer} ... todo finish javadoc + * Compiles a given {@link #jaxxFile} into a {@link #javaFile}. + * + * @author tchemit <chemit@codelutin.com> + * @since 1.0.0 */ public class JAXXCompiler { - /** - * Logger - */ + /** Logger */ protected static final Log log = LogFactory.getLog(JAXXCompiler.class); + /** - * True to throw exceptions when we encounter unresolvable classes, false to ignore. - * This is currently set to false until JAXX has full support for inner classes - * (including enumerations), because currently they don't always resolve (but will - * generally run without error anyway). + * True to throw exceptions when we encounter unresolvable classes, + * false to ignore. + * <p/> + * This is currently set to false until JAXX has full support for + * inner classes (including enumerations), because currently they don't + * always resolve (but will generally run without error anyway). */ public static final boolean STRICT_CHECKS = false; - /** - * - */ - public static final String JAXX_NAMESPACE = "http://www.jaxxframework.org/"; - /** - * - */ - public static final String JAXX_INTERNAL_NAMESPACE = "http://www.jaxxframework.org/internal"; - /** - * Maximum length of an inlinable creation method. - */ + + public static final String JAXX_NAMESPACE = + "http://www.jaxxframework.org/"; + + public static final String JAXX_INTERNAL_NAMESPACE = + "http://www.jaxxframework.org/internal"; + + /** Maximum length of an inlinable creation method. */ public static final int INLINE_THRESHOLD = 300; - /** - * Line separator cached value - */ - protected static String lineSeparator = System.getProperty("line.separator", "\n"); - /** - * The unique object handler used in first pass - */ + + /** Line separator cached value */ + protected static String lineSeparator = + System.getProperty("line.separator", "\n"); + + /** The unique object handler used in first pass */ protected final DefaultObjectHandler firstPassClassTagHandler; /*------------------------------------------------------------------------*/ /*-- compiler fields -----------------------------------------------------*/ /*------------------------------------------------------------------------*/ - /** - * flag to detect if an error occurs while compiling jaxx file - */ + + /** flag to detect if an error occurs while compiling jaxx file */ protected boolean failed; - /** - * Object corresponding to the root tag in the document. - */ + + /** Object corresponding to the root tag in the document. */ protected CompiledObject root; - /** - * Contains strings of the form "javax.swing." - */ - protected Set<String> importedPackages = new HashSet<String>(); - /** - * Contains strings of the form "javax.swing.Timer" - */ - protected Set<String> importedClasses = new HashSet<String>(); - /** - * Keeps track of open components (components still having children added). - */ - protected Stack<CompiledObject> openComponents = new Stack<CompiledObject>(); - /** - * to generate ids - */ + + /** Contains strings of the form "javax.swing." */ + protected Set<String> importedPackages; + + /** Contains strings of the form "javax.swing.Timer" */ + protected Set<String> importedClasses; + + /** Keeps track of open components (components still having children added). */ + protected Stack<CompiledObject> openComponents; + + /** to generate ids */ protected final IDHelper idHelper; - /** - * Binding Util - */ + + /** Binding Util */ protected final DataBindingHelper bindingHelper; + + /** table of symbols for this compiler */ + protected SymbolTable symbolTable; + /** - * table of symbols for this compiler - */ - protected SymbolTable symbolTable = new SymbolTable(); - /** * Base directory used for path resolution (normally the directory in * which the .jaxx file resides). */ protected File baseDir; - /** - * jaxx file being compiled. - */ + + /** jaxx file being compiled. */ protected File src; - /** - * Parsed XML of src file. - */ + + /** Parsed XML of src file. */ protected Document document; - /** - * Name of class being compiled. - */ + + /** Name of class being compiled. */ protected String outputClassName; + + /** script manager */ + protected ScriptManager scriptManager; + /** - * - */ - protected ScriptManager scriptManager = new ScriptManager(this); - /** * Combination of all stylesheets registered using * {@link #registerStylesheet}. */ protected Stylesheet stylesheet; + + /** Contains all attributes defined inline on class tags. */ + protected List<Rule> inlineStyles; + /** - * Contains all attributes defined inline on class tags. + * Maps objects (expressed in Java code) to event listener classes + * (e.g. MouseListener) to Lists of EventHandlers. The final list + * contains all event handlers of a particular type attached to a + * particular object (again, as represented by a Java expression). */ - protected List<Rule> inlineStyles = new ArrayList<Rule>(); + protected Map<String, Map<ClassDescriptor, List<EventHandler>>> eventHandlers; + + /** Map of event handler method names used in compiler */ + protected Map<EventHandler, String> eventHandlerMethodNames; + /** - * Maps objects (expressed in Java code) to event listener classes (e.g. MouseListener) to Lists of EventHandlers. The final list - * contains all event handlers of a particular type attached to a particular object (again, as represented by a Java expression). + * ClassLoader which searches the user-specified class path in + * addition to the normal class path */ - protected Map<String, Map<ClassDescriptor, List<EventHandler>>> eventHandlers = new HashMap<String, Map<ClassDescriptor, List<EventHandler>>>(); - /** - * Map of event handler method names used in compiler - */ - protected Map<EventHandler, String> eventHandlerMethodNames = new HashMap<EventHandler, String>(); - /** - * ClassLoader which searches the user-specified class path in addition to the normal class path - */ protected ClassLoader classLoader; + /** - * A list of Runnables which will be run after the first compilation pass. This is primarily used - * to trigger the creation of CompiledObjects, which cannot be created during the first pass and must be - * created in document order. + * A list of Runnables which will be run after the first compilation pass. + * <p/> + * This is primarily used to trigger the creation of CompiledObjects, + * which cannot be created during the first pass and must be created + * in document order. */ - protected List<Runnable> initializers = new ArrayList<Runnable>(); + protected List<Runnable> initializers; + /** - * extra interfaces which can by passed to root object via the 'implements' attribute + * extra interfaces which can by passed to root object via the + * 'implements' attribute */ private String[] extraInterfaces; - /** - * a flag to generate a abstract class - */ + + /** a flag to generate a abstract class */ private boolean abstractClass; - /** - * the possible generic type of the class - */ + + /** the possible generic type of the class */ private String genericType; - /** - * the possible generic type of the super class - */ + + /** the possible generic type of the super class */ private String superGenericType; - /** - * Extra code to be added to the instance initializer. - */ - protected StringBuffer initializer = new StringBuffer(); - /** - * Extra code to be added at the end of the instance initializer. - */ - protected StringBuffer lateInitializer = new StringBuffer(); - /** - * Extra code to be added to the class body. - */ - protected StringBuffer bodyCode = new StringBuffer(); - /** - * true if a main() method has been declared in a script - */ + + /** Extra code to be added to the instance initializer. */ + protected StringBuffer initializer; + + /** Extra code to be added at the end of the instance initializer. */ + protected StringBuffer lateInitializer; + + /** Extra code to be added to the class body. */ + protected StringBuffer bodyCode; + + /** true if a main() method has been declared in a script */ protected boolean mainDeclared; - /** - * the file to be generated - */ + + /** the file to be generated */ protected JavaFile javaFile; + + /** Used for error reporting purposes, so we can report the right line number. */ + protected Stack<Element> tagsBeingCompiled; + + /** Used for error reporting purposes, so we can report the right source file. */ + protected Stack<File> sourceFiles; + /** - * configuration of the compiler + * Maps object ID strings to the objects themselves. + * <p/> + * These are created during the second compilation pass. */ - protected CompilerConfiguration configuration; + protected Map<String, CompiledObject> objects; + /** - * Used for error reporting purposes, so we can report the right line number. + * Maps objects to their ID strings. + * <p/> + * These are created during the second compilation pass. */ - protected Stack<Element> tagsBeingCompiled = new Stack<Element>(); - /** - * Used for error reporting purposes, so we can report the right source file. - */ - protected Stack<File> sourceFiles = new Stack<File>(); - /** - * Maps object ID strings to the objects themselves. These are created during the second compilation pass. - */ - protected Map<String, CompiledObject> objects = new LinkedHashMap<String, CompiledObject>(); - /** - * Maps objects to their ID strings. These are created during the second compilation pass. - */ - protected Map<CompiledObject, String> ids = new LinkedHashMap<CompiledObject, String>(); - /** - * default decodator to use if none specified - */ + protected Map<CompiledObject, String> ids; + + /** default decodator to use if none specified */ protected CompiledObjectDecorator defaultDecorator; + /** - * engine which references this compiler (can be null if compiler is standalone) + * engine which references this compiler + * (can be null if compiler is standalone) */ protected final JAXXEngine engine; + protected final JAXXCompilerFile jaxxFile; + /** * Flag to know if jaxx file ident css was found, otherwise add it * when {@link CompilerConfiguration#isAutoImportCss()} is sets to {@code true} @@ -265,41 +279,67 @@ public static final String[] EMPTY_STRING_ARRAY = new String[0]; + public JAXXCompiler() { + this(null, null, null); + } + /** * Creates a new JAXXCompiler. * - * @param engine engine which use the compiler (could be null if not attach to any engine) - * @param baseDir classpath location - * @param src location of file to run - * @param outputClassName the out file name - * @param configuration configuration to pass to javac - * @param defaultImports list of default imports to add to java files + * @param engine engine which use the compiler (could be null if not attach to any engine) + * @param jaxxFile the file to compile + * @param defaultImports list of default imports to add to java files */ public JAXXCompiler(JAXXEngine engine, - File baseDir, - File src, - String outputClassName, - CompilerConfiguration configuration, + JAXXCompilerFile jaxxFile, List<String> defaultImports) { this.engine = engine; - this.baseDir = baseDir; - this.src = src; + this.jaxxFile = jaxxFile; + + ids = new LinkedHashMap<CompiledObject, String>(); + objects = new LinkedHashMap<String, CompiledObject>(); + bodyCode = new StringBuffer(); + lateInitializer = new StringBuffer(); + initializer = new StringBuffer(); + tagsBeingCompiled = new Stack<Element>(); + initializers = new ArrayList<Runnable>(); + eventHandlerMethodNames = new HashMap<EventHandler, String>(); + eventHandlers = + new HashMap<String, Map<ClassDescriptor, List<EventHandler>>>(); + inlineStyles = new ArrayList<Rule>(); + scriptManager = new ScriptManager(this); + symbolTable = new SymbolTable(); + openComponents = new Stack<CompiledObject>(); + importedPackages = new HashSet<String>(); + importedClasses = new HashSet<String>(); + sourceFiles = new Stack<File>(); + + if (jaxxFile == null) { + src = null; + baseDir = null; + outputClassName = null; + } else { + src = jaxxFile.getJaxxFile(); + baseDir = src.getParentFile(); + outputClassName = jaxxFile.getClassName(); + sourceFiles.push(src); + addImport(outputClassName.substring( + 0, outputClassName.lastIndexOf(".") + 1) + "*"); + } + firstPassClassTagHandler = new DefaultObjectHandler( ClassDescriptorLoader.getClassDescriptor(Object.class) ); - sourceFiles.push(src); - this.outputClassName = outputClassName; - this.configuration = configuration; - if (outputClassName != null) { - addImport(outputClassName.substring( - 0, outputClassName.lastIndexOf(".") + 1) + "*"); - } + bindingHelper = new DataBindingHelper(this); + if (defaultImports != null) { for (Object staticImport : defaultImports) { addImport((String) staticImport); } } - if (configuration != null) { + + if (engine != null) { + CompilerConfiguration configuration = engine.getConfiguration(); // add extra imports from configuration if (configuration.getExtraImports() != null) { for (String extraImport : configuration.getExtraImports()) { @@ -309,22 +349,21 @@ defaultDecorator = engine.getDecorator( configuration.getDefaultDecoratorClass()); if (defaultDecorator == null) { - log.error("could not find default decorator : " + - configuration.getDefaultDecoratorClass()); throw new IllegalArgumentException( "could not find default decorator : " + - configuration.getDefaultDecoratorClass()); + configuration.getDefaultDecoratorClass() + ); } idHelper = new IDHelper(configuration.isOptimize()); } else { idHelper = new IDHelper(false); } - bindingHelper = new DataBindingHelper(this); } /*------------------------------------------------------------------------*/ /*-- Initializer methods -------------------------------------------------*/ /*------------------------------------------------------------------------*/ + public void runInitializers() { for (Runnable runnable : initializers) { if (log.isDebugEnabled()) { @@ -354,6 +393,7 @@ /*------------------------------------------------------------------------*/ /*-- Compile methods -----------------------------------------------------*/ /*------------------------------------------------------------------------*/ + public void compileFirstPass(final Element tag) throws IOException { tagsBeingCompiled.push(tag); @@ -368,10 +408,13 @@ // class name is fully-qualified already fullClassName = TagManager.resolveClassName(localName, this); } else { - // namespace not included in class name, probably need the namespace to resolve - fullClassName = TagManager.resolveClassName(packageName + localName, this); + // namespace not included in class name, probably need the + // namespace to resolve + fullClassName = TagManager.resolveClassName( + packageName + localName, this); if (fullClassName == null && !namespacePrefix) { - // it was just a default namespace, try again without using the namespace + // it was just a default namespace, try again without + // using the namespace fullClassName = TagManager.resolveClassName(localName, this); } } @@ -382,43 +425,76 @@ if (fullClassName != null) { // we are definitely dealing with a class tag addDependencyClass(fullClassName); - namespace = fullClassName.substring(0, fullClassName.lastIndexOf(".") + 1) + "*"; + namespace = fullClassName.substring( + 0, fullClassName.lastIndexOf(".") + 1) + "*"; if (symbolTable.getSuperclassName() == null) { symbolTable.setSuperclassName(fullClassName); } String id = tag.getAttribute(DefaultObjectHandler.ID_ATTRIBUTE); + MethodDescriptor methodDescriptor; if (!id.isEmpty()) { symbolTable.getClassTagIds().put(id, fullClassName); if (tag.getAttributeNode(DefaultObjectHandler.JAVA_BEAN_ATTRIBUTE) != null) { // add java bean support for this property String capitalizeName = StringUtils.capitalize(id); // add method - symbolTable.getScriptMethods().add(new MethodDescriptor("get" + capitalizeName, Modifier.PUBLIC, fullClassName, EMPTY_STRING_ARRAY, classLoader)); + + methodDescriptor = new MethodDescriptor( + "get" + capitalizeName, + Modifier.PUBLIC, + fullClassName, + EMPTY_STRING_ARRAY, + classLoader + ); + symbolTable.getScriptMethods().add(methodDescriptor); if (Boolean.class.getName().equals(fullClassName)) { - symbolTable.getScriptMethods().add(new MethodDescriptor("is" + capitalizeName, Modifier.PUBLIC, fullClassName, EMPTY_STRING_ARRAY, classLoader)); + methodDescriptor = new MethodDescriptor( + "is" + capitalizeName, + Modifier.PUBLIC, + fullClassName, + EMPTY_STRING_ARRAY, + classLoader + ); + symbolTable.getScriptMethods().add(methodDescriptor); } - symbolTable.getScriptMethods().add(new MethodDescriptor("set" + capitalizeName, Modifier.PUBLIC, "void", new String[]{fullClassName}, classLoader)); + methodDescriptor = new MethodDescriptor( + "set" + capitalizeName, + Modifier.PUBLIC, + "void", + new String[]{fullClassName}, + classLoader + ); + symbolTable.getScriptMethods().add(methodDescriptor); } else { // add simple get support String capitalizeName = StringUtils.capitalize(id); // add method - symbolTable.getScriptMethods().add(new MethodDescriptor("get" + capitalizeName, Modifier.PUBLIC, fullClassName, EMPTY_STRING_ARRAY, classLoader)); + methodDescriptor = new MethodDescriptor( + "get" + capitalizeName, + Modifier.PUBLIC, + fullClassName, + EMPTY_STRING_ARRAY, + classLoader + ); + symbolTable.getScriptMethods().add(methodDescriptor); } } - String interfacesStr = tag.getAttribute(DefaultObjectHandler.IMPLEMENTS_ATTRIBUTE); + String interfacesStr = + tag.getAttribute(DefaultObjectHandler.IMPLEMENTS_ATTRIBUTE); if (!interfacesStr.isEmpty()) { // there is some interfaces to deal with StringTokenizer stk = new StringTokenizer(interfacesStr, ","); List<String> tmp = new ArrayList<String>(); while (stk.hasMoreTokens()) { String c = stk.nextToken(); - if (c.indexOf("<") != -1 && c.indexOf(">") == -1) { - // deal with a generic interface with more than one parameter + if (c.contains("<") && !c.contains(">")) { + // deal with a generic interface with more than one + // parameter boolean done = false; while (stk.hasMoreTokens()) { String next = stk.nextToken(); - if (next.indexOf(">") == -1) { + if (!next.contains(">")) { // still a parameter of the generic type continue; } @@ -428,7 +504,9 @@ } if (!done) { // the syntax is not valid (missed one >) - throw new CompilerException("Syntax error of interfaces " + interfacesStr); + throw new CompilerException( + "Syntax error of interfaces " + + interfacesStr); } c = c.substring(0, c.indexOf("<")); } @@ -436,41 +514,63 @@ } String[] interfaces = tmp.toArray(new String[tmp.size()]); if (log.isDebugEnabled()) { - log.debug("detect interfaces : " + Arrays.toString(interfaces)); + log.debug("detect interfaces : " + + Arrays.toString(interfaces)); } symbolTable.setInterfaces(interfaces); } } - // during the first pass, we can't create ClassDescriptors for JAXX files because they may not have been processed yet - // (and we can't wait until they have been processed because of circular dependencies). So we don't do any processing - // during the first pass which requires having a ClassDescriptor; here we determine whether we have a class tag or not - // (class tag namespaces end in "*") and use a generic handler if so. The real handler is used during the second pass. + // during the first pass, we can't create ClassDescriptors for JAXX + // files because they may not have been processed yet (and we can't + // wait until they have been processed because of circular + // dependencies). + // So we don't do any processing during the first pass which requires + // having a ClassDescriptor; here we determine whether we have a class + // tag or not (class tag namespaces end in "*") and use a generic + // handler if so. + // The real handler is used during the second pass. TagHandler handler = namespace != null && namespace.endsWith("*") ? firstPassClassTagHandler : - TagManager.getTagHandler(tag.getNamespaceURI(), localName, namespacePrefix, this); - if (!firstPassClassTagHandler.equals(handler) && handler instanceof DefaultObjectHandler) { - fullClassName = ((DefaultObjectHandler) handler).getBeanClass().getName(); - //namespace = fullClassName.substring(0, fullClassName.lastIndexOf(".") + 1) + "*"; + TagManager.getTagHandler(tag.getNamespaceURI(), + localName, + namespacePrefix, + this + ); + if (!firstPassClassTagHandler.equals(handler) && + handler instanceof DefaultObjectHandler) { + fullClassName = + ((DefaultObjectHandler) handler).getBeanClass().getName(); handler = firstPassClassTagHandler; } if (firstPassClassTagHandler.equals(handler)) { final String finalClassName = fullClassName; + + // register an initializer which will create the + // CompiledObject after pass 1 + registerInitializer(new Runnable() { - // register an initializer which will create the CompiledObject after pass 1 @Override public void run() { - DefaultObjectHandler handler = (DefaultObjectHandler) TagManager.getTagHandler(null, finalClassName, JAXXCompiler.this); + DefaultObjectHandler handler = + (DefaultObjectHandler) TagManager.getTagHandler( + null, + finalClassName, + JAXXCompiler.this + ); if (handler == null) { - throw new CompilerException("Internal error: missing TagHandler for '" + finalClassName + "'"); + throw new CompilerException( + "Internal error: missing TagHandler for '" + + finalClassName + "'"); } handler.registerCompiledObject(tag, JAXXCompiler.this); } }); } if (handler == null) { - reportError("Could not find a Java class corresponding to: <" + tag.getTagName() + ">"); + reportError("Could not find a Java class corresponding to: <" + + tag.getTagName() + ">"); failed = true; } else { try { @@ -482,28 +582,39 @@ Element finished = tagsBeingCompiled.pop(); if (finished != tag) { - throw new IllegalStateException("internal error: just finished compiling " + tag + ", but top of tagsBeingCompiled stack is " + finished); + throw new IllegalStateException( + "internal error: just finished compiling " + tag + + ", but top of tagsBeingCompiled stack is " + finished); } } public void compileSecondPass(Element tag) throws IOException { tagsBeingCompiled.push(tag); - TagHandler handler = TagManager.getTagHandler(tag.getNamespaceURI(), tag.getLocalName(), tag.getPrefix() != null, this); + TagHandler handler = TagManager.getTagHandler( + tag.getNamespaceURI(), + tag.getLocalName(), + tag.getPrefix() != null, + this + ); + if (handler == null) { - reportError("Could not find a Java class corresponding to: <" + tag.getTagName() + ">"); + reportError("Could not find a Java class corresponding to: <" + + tag.getTagName() + ">"); failed = true; } else { handler.compileSecondPass(tag, this); } Element finished = tagsBeingCompiled.pop(); - if (finished != tag) { - throw new RuntimeException("internal error: just finished compiling " + tag + ", but top of tagsBeingCompiled stack is " + finished); + if (!tag.equals(finished)) { + throw new RuntimeException( + "internal error: just finished compiling " + tag + + ", but top of tagsBeingCompiled stack is " + finished); } } - protected void compileFirstPass() throws IOException { + public void compileFirstPass() throws IOException { InputStream in = new FileInputStream(src); try { document = parseDocument(in); @@ -517,9 +628,11 @@ } } - protected void compileSecondPass() throws IOException { + public void compileSecondPass() throws IOException { if (!tagsBeingCompiled.isEmpty()) { - throw new RuntimeException("Internal error: starting pass two, but tagsBeingCompiled is not empty: " + tagsBeingCompiled); + throw new RuntimeException( + "Internal error: starting pass two, but tagsBeingCompiled" + + " is not empty: " + tagsBeingCompiled); } compileSecondPass(document.getDocumentElement()); } @@ -527,11 +640,13 @@ /*------------------------------------------------------------------------*/ /*-- CompiledObject methods ----------------------------------------------*/ /*------------------------------------------------------------------------*/ + public void openComponent(CompiledObject component) throws CompilerException { openComponent(component, null); } - public void openComponent(CompiledObject component, String constraints) throws CompilerException { + public void openComponent(CompiledObject component, + String constraints) throws CompilerException { CompiledObject parent = getOpenComponent(); openInvisibleComponent(component); if (parent != null && !component.isOverride()) { @@ -554,20 +669,29 @@ } public void closeComponent(CompiledObject component) { - if (openComponents.pop() != component) { - throw new IllegalArgumentException("can only close the topmost open object"); + if (component == null) { + throw new NullPointerException("can not close a null component"); } + if (!component.equals(openComponents.pop())) { + throw new IllegalArgumentException( + "can only close the topmost open object"); + } } public void registerCompiledObject(CompiledObject object) { - assert engine.symbolTables.values().contains(symbolTable) : "attempting to register CompiledObject before pass 1 is complete"; +// assert engine.symbolTables.values().contains(symbolTable) : +// "attempting to register CompiledObject before pass 1 is complete"; if (root == null) { root = object; } String id = object.getId(); if (ids.containsKey(object)) { - reportError("object '" + object + "' is already registered with id '" + ids.get(object) + "', cannot re-register as '" + id + "'"); + reportError("object '" + object + + "' is already registered with id '" + + ids.get(object) + "', cannot re-register as '" + id + + "'" + ); } if (objects.containsKey(id) && !(objects.get(id) instanceof Element)) { reportError("id '" + id + "' is already registered to component " + objects.get(id)); @@ -582,12 +706,14 @@ public CompiledObject getCompiledObject(String id) { runInitializers(); - assert engine.symbolTables.values().contains(symbolTable) : "attempting to retrieve CompiledObject before pass 1 is complete"; +// assert engine.symbolTables.values().contains(symbolTable) : +// "attempting to retrieve CompiledObject before pass 1 is complete"; return objects.get(id); } public boolean inlineCreation(CompiledObject object) { - return object.getId().startsWith("$") && object.getInitializationCode(this).length() < INLINE_THRESHOLD; + return object.getId().startsWith("$") && + object.getInitializationCode(this).length() < INLINE_THRESHOLD; } public void checkOverride(CompiledObject object) throws CompilerException { @@ -600,9 +726,15 @@ } while (ancestor != null) { try { - FieldDescriptor f = ancestor.getDeclaredFieldDescriptor(object.getId()); + FieldDescriptor f = + ancestor.getDeclaredFieldDescriptor(object.getId()); if (!f.getType().isAssignableFrom(object.getObjectClass())) { - reportError("attempting to redefine superclass member '" + object.getId() + "' as incompatible type (was " + f.getType() + ", redefined as " + object.getObjectClass() + ")"); + reportError( + "attempting to redefine superclass member '" + + object.getId() + "' as incompatible type (was " + + f.getType() + ", redefined as " + + object.getObjectClass() + ")" + ); } object.setOverride(true); object.setOverrideType(f.getType()); @@ -623,7 +755,8 @@ public void registerEventHandler(EventHandler handler) { String objectCode = handler.getObjectCode(); - Map<ClassDescriptor, List<EventHandler>> listeners = eventHandlers.get(objectCode); + Map<ClassDescriptor, List<EventHandler>> listeners = + eventHandlers.get(objectCode); if (listeners == null) { listeners = new HashMap<ClassDescriptor, List<EventHandler>>(); eventHandlers.put(objectCode, listeners); @@ -645,7 +778,8 @@ } else { //TC-20090309 must get the goal property from the event id // to make possible inheritance - String id = handler.getEventId().substring(0, handler.getEventId().indexOf(".")); + String id = handler.getEventId().substring( + 0, handler.getEventId().indexOf(".")); result = "do" + StringUtils.capitalize(handler.getListenerMethod().getName()) + "__on__" + id; //TC-20091105 : check the method name is available @@ -668,12 +802,15 @@ /*------------------------------------------------------------------------*/ /*-- Script methods ------------------------------------------------------*/ /*------------------------------------------------------------------------*/ + public void addScriptField(FieldDescriptor field) { symbolTable.getScriptFields().add(field); } public void addScriptMethod(MethodDescriptor method) { - if (method.getName().equals("main") && method.getParameterTypes().length == 1 && method.getParameterTypes()[0].getName().equals("[Ljava.lang.String;")) { + if (method.getName().equals("main") && + method.getParameterTypes().length == 1 && + method.getParameterTypes()[0].getName().equals("[Ljava.lang.String;")) { setMainDeclared(true); } symbolTable.getScriptMethods().add(method); @@ -683,19 +820,21 @@ registerScript(script, null); } - public void registerScript(String script, File sourceFile) throws CompilerException { + public void registerScript(String script, + File sourceFile) throws CompilerException { if (sourceFile != null) { sourceFiles.push(sourceFile); } script = script.trim(); - if (!"".equals(script) && !script.endsWith("}") && !script.endsWith(";")) { + if (!"".equals(script) && !script.endsWith("}") && + !script.endsWith(";")) { script += ";"; } scriptManager.registerScript(script); if (sourceFile != null) { File pop = sourceFiles.pop(); - if (pop != sourceFile) { + if (!sourceFile.equals(pop)) { throw new RuntimeException( "leaving registerScript(), but " + sourceFile + " was not the top entry on the stack (found " + pop @@ -712,15 +851,15 @@ /*-- StyleSheet methods --------------------------------------------------*/ /*------------------------------------------------------------------------*/ - public File getIdentCssFile() { - String extension = FileUtil.extension(src); - String jaxxFileName = src.getName(); - String identCssFilename = jaxxFileName.substring( - 0, - jaxxFileName.length() - extension.length()) + "css"; - File identCssFile = new File(src.getParentFile(), identCssFilename); - return identCssFile; - } +// public File getIdentCssFile() { +// String extension = FileUtil.extension(src); +// String jaxxFileName = src.getName(); +// String identCssFilename = jaxxFileName.substring( +// 0, +// jaxxFileName.length() - extension.length()) + "css"; +// File identCssFile = new File(src.getParentFile(), identCssFilename); +// return identCssFile; +// } public boolean isIdentCssFound() { return identCssFound; @@ -730,17 +869,15 @@ if (!identCssFound && getConfiguration().isAutoImportCss()) { // detects if the given css file is ident to jaxx file - File identCssFile = getIdentCssFile(); + File identCssFile = jaxxFile.getCssFile(); if (identCssFile.exists()) { // ok found ident css file identCssFound = true; - reportWarning("autoImportCss mode is on, you can remove style declaration with source " + styleFile); -// if (getConfiguration().isVerbose()) { -// log.info("Ident css found : " + identCssFile); -// } + reportWarning("autoImportCss mode is on, you can remove " + + "style declaration with source " + styleFile); } } @@ -755,14 +892,16 @@ getSourceFiles().pop(); } } + public void applyStylesheets() { for (Object o : new ArrayList<CompiledObject>(objects.values())) { CompiledObject object = (CompiledObject) o; - DefaultObjectHandler tagHandler = TagManager.getTagHandler(object.getObjectClass()); + DefaultObjectHandler tagHandler = + TagManager.getTagHandler(object.getObjectClass()); if (log.isDebugEnabled()) { - log.debug("will apply css on object " + object.getId()+" from handler " + tagHandler); + log.debug("will apply css on object " + object.getId() + + " from handler " + tagHandler); } - tagHandler.applyStylesheets(object, this); } } @@ -775,13 +914,21 @@ } } - public void addInlineStyle(CompiledObject object, String propertyName, boolean dataBinding) { - inlineStyles.add(StylesheetHelper.inlineAttribute(object, propertyName, dataBinding)); + public void addInlineStyle(CompiledObject object, + String propertyName, + boolean dataBinding) { + Rule style = StylesheetHelper.inlineAttribute( + object, + propertyName, + dataBinding + ); + inlineStyles.add(style); } /*------------------------------------------------------------------------*/ /*-- Report methods ------------------------------------------------------*/ /*------------------------------------------------------------------------*/ + public void reportWarning(String warning) { Element currentTag = null; if (!tagsBeingCompiled.isEmpty()) { @@ -793,7 +940,8 @@ public void reportWarning(Element tag, String warning, int lineOffset) { String lineNumber = null; if (tag != null) { - String lineAttr = tag.getAttributeNS(JAXX_INTERNAL_NAMESPACE, "line"); + String lineAttr = + tag.getAttributeNS(JAXX_INTERNAL_NAMESPACE, "line"); if (lineAttr.length() > 0) { lineNumber = lineAttr; } @@ -807,7 +955,11 @@ StringBuilder buffer = new StringBuilder(); buffer.append(srcFile); if (lineNumber != null) { - buffer.append(":").append(sourceFiles.size() == 1 ? Integer.parseInt(lineNumber) + lineOffset : lineOffset + 1); + buffer.append(":"); + buffer.append(sourceFiles.size() == 1 ? + Integer.parseInt(lineNumber) + lineOffset : + lineOffset + 1 + ); } buffer.append(getLineSeparator()).append(warning.trim()); if (engine != null) { @@ -831,8 +983,11 @@ public void reportError(String extraMessage, CompilerException ex) { String message = ex.getMessage(); - if (UnsupportedAttributeException.class.equals(ex.getClass()) || UnsupportedTagException.class.equals(ex.getClass())) { - message = ex.getClass().getName().substring(ex.getClass().getName().lastIndexOf(".") + 1) + ": " + message; + if (UnsupportedAttributeException.class.equals(ex.getClass()) || + UnsupportedTagException.class.equals(ex.getClass())) { + String exceptionName = ex.getClass().getName(); + message = exceptionName.substring( + exceptionName.lastIndexOf(".") + 1) + ": " + message; } int lineOffset; if (ex instanceof ParseException) { @@ -844,7 +999,10 @@ if (!tagsBeingCompiled.isEmpty()) { currentTag = tagsBeingCompiled.peek(); } - reportError(currentTag, extraMessage != null ? extraMessage + message : message, lineOffset); + reportError(currentTag, extraMessage != null ? + extraMessage + message : + message, lineOffset + ); } public void reportError(Element tag, String error) { @@ -854,7 +1012,8 @@ public void reportError(Element tag, String error, int lineOffset) { int lineNumber = 0; if (tag != null) { - String lineAttr = tag.getAttributeNS(JAXX_INTERNAL_NAMESPACE, "line"); + String lineAttr = + tag.getAttributeNS(JAXX_INTERNAL_NAMESPACE, "line"); if (lineAttr.length() > 0) { lineNumber = Integer.parseInt(lineAttr); } @@ -873,7 +1032,8 @@ // ignore ? } StringBuilder buffer = new StringBuilder(); - buffer.append(errorFile != null ? errorFile.getPath() : "<unknown source>"); + buffer.append(errorFile != null ? errorFile.getPath() : + "<unknown source>"); if (lineNumber > 0) { buffer.append(":").append(lineNumber); } @@ -889,6 +1049,7 @@ /*------------------------------------------------------------------------*/ /*-- Getter methods ------------------------------------------------------*/ /*------------------------------------------------------------------------*/ + public Map<String, CompiledObject> getObjects() { return objects; } @@ -898,7 +1059,7 @@ } public CompilerConfiguration getConfiguration() { - return configuration; + return getEngine().getConfiguration(); } public String getOutputClassName() { @@ -948,7 +1109,8 @@ public FieldDescriptor[] getScriptFields() { List<FieldDescriptor> scriptFields = symbolTable.getScriptFields(); - return scriptFields.toArray(new FieldDescriptor[scriptFields.size()]); + return scriptFields.toArray( + new FieldDescriptor[scriptFields.size()]); } public FieldDescriptor getScriptField(String fieldName) { @@ -962,7 +1124,8 @@ public MethodDescriptor[] getScriptMethods() { List<MethodDescriptor> scriptMethods = symbolTable.getScriptMethods(); - return scriptMethods.toArray(new MethodDescriptor[scriptMethods.size()]); + return scriptMethods.toArray( + new MethodDescriptor[scriptMethods.size()]); } public MethodDescriptor getScriptMethod(String methodName) { @@ -983,17 +1146,20 @@ } /** - * Returns a <code>ClassLoader</code> which searches the user-specified class path in addition - * to the normal system class path. + * Returns a <code>ClassLoader</code> which searches the user-specified + * class path in addition to the normal system class path. * * @return <code>ClassLoader</code> to use while resolving class references */ public ClassLoader getClassLoader() { if (classLoader == null) { + CompilerConfiguration configuration = getConfiguration(); if (configuration.getClassLoader() != null) { classLoader = configuration.getClassLoader(); } else { - throw new NullPointerException("compiler configuration requires a classLoader! :\n" + configuration); + throw new NullPointerException( + "compiler configuration requires a classLoader! :\n" + + configuration); } } @@ -1002,12 +1168,18 @@ public JAXXObjectDescriptor getJAXXObjectDescriptor() { runInitializers(); - CompiledObject[] components = new ArrayList<CompiledObject>(objects.values()).toArray(new CompiledObject[objects.size()]); - assert initializers.isEmpty() : "there are pending initializers remaining"; + CompiledObject[] components = new ArrayList<CompiledObject>( + objects.values()).toArray(new CompiledObject[objects.size()]); + + assert initializers.isEmpty() : + "there are pending initializers remaining"; assert root != null : "root object has not been defined"; - assert Arrays.asList(components).contains(root) : "root object is not registered"; - ComponentDescriptor[] descriptors = new ComponentDescriptor[components.length]; - // as we print, sort the array so that component's parents are always before the components themselves + assert Arrays.asList(components).contains(root) : + "root object is not registered"; + ComponentDescriptor[] descriptors = + new ComponentDescriptor[components.length]; + // as we print, sort the array so that component's parents are always + // before the components themselves for (int i = 0; i < components.length; i++) { CompiledObject parent = components[i].getParent(); while (parent != null) { @@ -1036,8 +1208,10 @@ } } descriptors[i] = new ComponentDescriptor( - components[i].getId(), components[i] == root ? outputClassName : components[i].getObjectClass().getName(), - components[i].getStyleClass(), parentIndex != -1 ? descriptors[parentIndex] : null); + components[i].getId(), + components[i] == root ? outputClassName : components[i].getObjectClass().getName(), + components[i].getStyleClass(), + parentIndex != -1 ? descriptors[parentIndex] : null); } Stylesheet css = getStylesheet(); @@ -1051,6 +1225,7 @@ /*------------------------------------------------------------------------*/ /*-- Buffer --------------------------------------------------------------*/ /*------------------------------------------------------------------------*/ + public StringBuffer getInitializer() { return initializer; } @@ -1096,6 +1271,7 @@ /*------------------------------------------------------------------------*/ /*-- Other methods -------------------------------------------------------*/ /*------------------------------------------------------------------------*/ + public void addImport(String text) { if (text.endsWith("*")) { importedPackages.add(text.substring(0, text.length() - 1)); @@ -1110,47 +1286,67 @@ public void addDependencyClass(String className) { - if (!engine.containsJaxxFileClassName(className)) { - URL jaxxURL = getClassLoader().getResource(className.replace('.', '/') + ".jaxx"); - URL classURL = getClassLoader().getResource(className.replace('.', '/') + ".class"); - if (jaxxURL != null && classURL != null) { - try { - File jaxxFile = URLtoFile(jaxxURL); - File classFile = URLtoFile(classURL); - if (classFile.lastModified() > jaxxFile.lastModified()) { - return; // class file is newer, no need to recompile - } - } catch (Exception e) { - // do nothing - } + if (engine.containsJaxxFileClassName(className)) { + + // already registred in engine + return; + } + + // register the jaxx file into the engine + URL jaxxURL = getClassLoader().getResource( + className.replace('.', '/') + ".jaxx"); + URL classURL = getClassLoader().getResource( + className.replace('.', '/') + ".class"); + if (jaxxURL == null || classURL == null) { + + // unknown class + //FIXME-TC20100502 : should throw something or at least warn + return; + } + + try { + File jaxxFile = URLtoFile(jaxxURL); + File classFile = URLtoFile(classURL); + if (classFile.lastModified() > jaxxFile.lastModified()) { + return; // class file is newer, no need to recompile } + } catch (Exception e) { + // do nothing + } - if (jaxxURL != null && jaxxURL.toString().startsWith("file:")) { - File jaxxFile = URLtoFile(jaxxURL); - try { - jaxxFile = jaxxFile.getCanonicalFile(); - } catch (IOException ex) { - // ignore ? + if (jaxxURL.toString().startsWith("file:")) { + File jaxxFile = URLtoFile(jaxxURL); + try { + jaxxFile = jaxxFile.getCanonicalFile(); + } catch (IOException ex) { + // ignore ? + } + String jaxxFileName = + className.substring(className.lastIndexOf(".") + 1) + + ".jaxx"; + + assert jaxxFile.getName().equalsIgnoreCase(jaxxFileName) : + "expecting file name to match " + + className + ", but found " + jaxxFile.getName(); + if (jaxxFile.getName().equals(jaxxFileName)) { // check case match + if (!engine.isFirstCompilePassTask()) { + throw new AssertionError( + "Internal error: adding dependency class " + + className + " during second compilation pass"); } - 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 (engine.getCurrentPass() != JAXXEngine.LifeCycle.compile_first_pass) { - throw new AssertionError("Internal error: adding dependency class " + className + " during second compilation pass"); - } - engine.addJaxxFileClassName(className); - engine.addJaxxFile(jaxxFile); - } + engine.addFileToCompile(jaxxFile, className); } } } /** - * Verifies that a snippet of Java code parses correctly. A warning is generated if the string has enclosing - * curly braces. + * Verifies that a snippet of Java code parses correctly. + * <p/> + * A warning is generated if the string has enclosing curly braces. * * @param javaCode the Java code snippet to test - * @return a "cooked" version of the string which has enclosing curly braces removed. + * @return a "cooked" version of the string which has enclosing curly + * braces removed. * @throws CompilerException if the code cannot be parsed */ public String checkJavaCode(String javaCode) { @@ -1165,18 +1361,26 @@ * @param tag the current tag * @param reference the required reference * @param strict flag to report an error if reference was not found - * @param attribute (if not null reference the attribute where is defined the reference) - * @return <code>true</code> if reference was found, <code>false</code> otherwise and add an error in compiler + * @param attribute (if not null reference the attribute where is defined + * the reference) + * @return <code>true</code> if reference was found, <code>false</code> + * otherwise and add an error in compiler */ - public boolean checkReference(Element tag, String reference, boolean strict, String attribute) { + public boolean checkReference(Element tag, + String reference, + boolean strict, + String attribute) { String component = getSymbolTable().getClassTagIds().get(reference); if (component == null) { if (strict) { String msg; if (attribute != null) { - msg = "tag '" + tag.getLocalName() + "' could not find the reference '" + reference + "' on attribute [" + attribute + "]"; + msg = "tag '" + tag.getLocalName() + + "' could not find the reference '" + reference + + "' on attribute [" + attribute + "]"; } else { - msg = "tag '" + tag.getLocalName() + "' could not find the reference '" + reference + "'"; + msg = "tag '" + tag.getLocalName() + + "' could not find the reference '" + reference + "'"; } reportError(msg); } @@ -1236,10 +1440,11 @@ return javaFile; } - public void finalizeCompiler(Iterable<JAXXCompilerFinalizer> finalizers) throws Exception { + public void finalizeCompiler() throws Exception { int dotPos = getOutputClassName().lastIndexOf("."); - String packageName = dotPos != -1 ? getOutputClassName().substring(0, dotPos) : null; + String packageName = dotPos != -1 ? + getOutputClassName().substring(0, dotPos) : null; String simpleClassName = getOutputClassName().substring(dotPos + 1); CompiledObject compiledObject = getRootObject(); @@ -1247,13 +1452,22 @@ for (CompiledObject object : getObjects().values()) { CompiledObjectDecorator decorator = object.getDecorator(); - decorator.finalizeCompiler(this, root, object, javaFile, packageName, simpleClassName, getOutputClassName()); + decorator.finalizeCompiler(this, + root, + object, + javaFile, + packageName, + simpleClassName, + getOutputClassName() + ); } - // obtain listy of finalizers to apply + // obtain list of finalizers to apply - List<JAXXCompilerFinalizer> realFinalizers = new ArrayList<JAXXCompilerFinalizer>(); - for (JAXXCompilerFinalizer finalizer : finalizers) { + List<JAXXCompilerFinalizer> realFinalizers = + new ArrayList<JAXXCompilerFinalizer>(); + for (JAXXCompilerFinalizer finalizer : + getConfiguration().getFinalizers().values()) { if (finalizer.accept(this)) { realFinalizers.add(finalizer); } @@ -1264,7 +1478,12 @@ for (JAXXCompilerFinalizer finalizer : realFinalizers) { // check if finalizer can be apply of this compiler if (finalizer.accept(this)) { - finalizer.finalizeCompiler(compiledObject, this, javaFile, packageName, simpleClassName); + finalizer.finalizeCompiler(compiledObject, + this, + javaFile, + packageName, + simpleClassName + ); } } @@ -1281,22 +1500,40 @@ // call the finalizers prepareJavaFile method for (JAXXCompilerFinalizer finalizer : realFinalizers) { - finalizer.prepareJavaFile(compiledObject, this, javaFile, packageName, simpleClassName); + finalizer.prepareJavaFile(compiledObject, + this, + javaFile, + packageName, + simpleClassName + ); } } public void generate(JavaFileGenerator generator) throws IOException { File dest; + String fqn = getOutputClassName(); if (getConfiguration().getTargetDirectory() != null) { - dest = new File(getConfiguration().getTargetDirectory(), getOutputClassName().replace('.', File.separatorChar) + ".java"); + dest = new File(getConfiguration().getTargetDirectory(), + fqn.replace('.', File.separatorChar) + ".java" + ); } else { - dest = new File(getBaseDir(), getOutputClassName().substring(getOutputClassName().lastIndexOf(".") + 1) + ".java"); + dest = new File(getBaseDir(), + fqn.substring(fqn.lastIndexOf(".") + 1) + ".java" + ); } + + // make sure directory exists + File parentFile = dest.getParentFile(); + if (parentFile == null) { + throw new IOException("No parent file for " + dest); + } + if (!parentFile.exists() && !parentFile.mkdirs()) { + throw new IOException("Could not create directory " + parentFile); + } if (dest.exists() && !dest.setLastModified(System.currentTimeMillis())) { log.warn("could not touch file " + dest); } - PrintWriter out = null; - out = new PrintWriter(new FileWriter(dest)); + PrintWriter out = new PrintWriter(new FileWriter(dest)); try { generator.generateFile(javaFile, out); } finally { @@ -1314,6 +1551,7 @@ } // 1.5 adds getCanonicalName; unfortunately we can't depend on 1.5 features yet + public static String getCanonicalName(Class<?> clazz) { if (clazz.isArray()) { String canonicalName = getCanonicalName(clazz.getComponentType()); @@ -1357,11 +1595,12 @@ } /** - * Escapes a string using standard Java escape sequences, generally in preparation to including it in a string literal - * in a compiled Java file. + * Escapes a string using standard Java escape sequences, generally in + * preparation to including it in a string literal in a compiled Java file. * * @param raw the raw string to be escape - * @return a string in which all 'dangerous' characters have been replaced by equivalent Java escape sequences + * @return a string in which all 'dangerous' characters have been replaced + * by equivalent Java escape sequences */ public static String escapeJavaString(String raw) { StringBuffer out = new StringBuffer(raw); @@ -1397,11 +1636,13 @@ throw new IllegalArgumentException("url must start with 'file:'"); } urlString = urlString.substring("file:".length()); - if (urlString.startsWith("/") && System.getProperty("os.name").startsWith("Windows")) { + if (urlString.startsWith("/") && + System.getProperty("os.name").startsWith("Windows")) { urlString = urlString.substring(1); } try { - return new File(URLDecoder.decode(urlString.replace('/', File.separatorChar), "utf-8")); + return new File(URLDecoder.decode( + urlString.replace('/', File.separatorChar), "utf-8")); } catch (UnsupportedEncodingException e) { throw new RuntimeException(e); } @@ -1428,38 +1669,55 @@ transformer.setErrorListener(new ErrorListener() { @Override - public void warning(TransformerException ex) throws TransformerException { + public void warning( + TransformerException ex) throws TransformerException { throw ex; } @Override - public void error(TransformerException ex) throws TransformerException { + public void error( + TransformerException ex) throws TransformerException { throw ex; } @Override - public void fatalError(TransformerException ex) throws TransformerException { + public void fatalError( + TransformerException ex) throws TransformerException { throw ex; } }); DOMResult result = new DOMResult(); - transformer.transform(new SAXSource(new XMLFilterImpl(getSAXParser().getXMLReader()) { + transformer.transform( + new SAXSource(new XMLFilterImpl(getSAXParser().getXMLReader()) { - Locator locator; + Locator locator; - @Override - public void setDocumentLocator(Locator locator) { - this.locator = locator; - } + @Override + public void setDocumentLocator(Locator locator) { + this.locator = locator; + } - @Override - public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException { - AttributesImpl resultAtts = new AttributesImpl(atts); - resultAtts.addAttribute(JAXX_INTERNAL_NAMESPACE, "line", "internal:line", "CDATA", String.valueOf(locator.getLineNumber())); - getContentHandler().startElement(uri, localName, qName, resultAtts); - } - }, new InputSource(in)), result); + @Override + public void startElement(String uri, + String localName, + String qName, + Attributes atts) throws SAXException { + AttributesImpl resultAtts = new AttributesImpl(atts); + resultAtts.addAttribute( + JAXX_INTERNAL_NAMESPACE, + "line", + "internal:line", + "CDATA", + String.valueOf(locator.getLineNumber()) + ); + getContentHandler().startElement(uri, + localName, + qName, + resultAtts + ); + } + }, new InputSource(in)), result); return (Document) result.getNode(); } catch (TransformerConfigurationException e) { throw new RuntimeException(e); @@ -1490,6 +1748,16 @@ bindingHelper.clear(); objects.clear(); ids.clear(); + if (symbolTable != null) { + symbolTable.clear(); + } } + public void setIdentCssFound(boolean identCssFound) { + this.identCssFound = identCssFound; + } + + public void setClassLoader(ClassLoader classLoader) { + this.classLoader = classLoader; + } } Added: trunk/jaxx-compiler/src/main/java/jaxx/compiler/JAXXCompilerFile.java =================================================================== --- trunk/jaxx-compiler/src/main/java/jaxx/compiler/JAXXCompilerFile.java (rev 0) +++ trunk/jaxx-compiler/src/main/java/jaxx/compiler/JAXXCompilerFile.java 2010-05-02 16:55:27 UTC (rev 1865) @@ -0,0 +1,195 @@ +/* + * #%L + * JAXX :: Compiler + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2008 - 2010 CodeLutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ +package jaxx.compiler; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.nuiton.util.FileUtil; + +import java.io.File; + +/** + * Represents a file to be treated by the {@link JAXXCompiler}. + * <p/> + * It contains informations about jaxx file, ident css, class name,... + * <p/> + * <b>Note:</b> This class will be more used in next version (will have the + * compiler it-self, symbols table,...). + * + * @author tchemit <chemit@codelutin.com> + * @since 2.0.2 + */ +public class JAXXCompilerFile { + + /** Logger */ + private static final Log log = LogFactory.getLog(JAXXCompilerFile.class); + + /** root directory of the source roots. */ + protected final File basedir; + + /** relative path from {@link #basedir} to {@link #jaxxFile}. */ + private final String relativePath; + + /** location of the jaxx file */ + protected File jaxxFile; + + /** location of the ident css file */ + protected File cssFile; + + /** full qualified name of the jaxx file class */ + protected String className; + + /** compiler associated to the file */ + protected JAXXCompiler compiler; + + public JAXXCompilerFile(File basedir, File jaxxFile) { + this.basedir = basedir; + this.jaxxFile = jaxxFile; + String absolutePath = jaxxFile.getAbsolutePath(); + String baseAbsolutePath = basedir.getAbsolutePath(); + if (!absolutePath.startsWith(baseAbsolutePath)) { + throw new IllegalStateException( + "Jaxx file " + jaxxFile + " is not in basedir " + basedir); + } + + relativePath = absolutePath.substring(baseAbsolutePath.length() + 1); + if (log.isDebugEnabled()) { + log.debug("relativePath = " + relativePath); + } + } + + public JAXXCompilerFile(File jaxxFile, String className) { + + this.jaxxFile = jaxxFile; + this.className = className; + + String extension = FileUtil.extension(jaxxFile); + String[] paths = className.split("\\."); + File basedir = jaxxFile; + for (int i = paths.length - 1; i > -1; i--) { + if (basedir == null) { + throw new IllegalStateException( + "Could not find base dir for " + jaxxFile + + " according to fqn " + className + ); + } + + String path = paths[i]; + if (basedir.equals(jaxxFile)) { + // first in loop + path += "." + extension; + } + + // check path = base filename + if (!path.equals(basedir.getName())) { + throw new IllegalStateException( + "Should have found directory " + path + ", but was " + + basedir.getName() + ); + } + + basedir = basedir.getParentFile(); + } + + if (log.isDebugEnabled()) { + log.debug("basedir = " + basedir); + } + + // must guess the base directory and relative path + + String relativePath = jaxxFile.getAbsolutePath().substring( + basedir.getAbsolutePath().length() + 1 + ); + + if (log.isDebugEnabled()) { + log.debug("relative path = " + relativePath); + } + + this.basedir = basedir; + this.relativePath = relativePath; + } + + public File getBasedir() { + return basedir; + } + + public String getRelativePath() { + return relativePath; + } + + public JAXXCompiler getCompiler() { + return compiler; + } + +// public SymbolTable getSymbolTable() { +// return compiler==null?null:compiler.getSymbolTable(); +// } + + public File getJaxxFile() { + if (jaxxFile == null) { + jaxxFile = new File(basedir, relativePath); + } + return jaxxFile; + } + + public File getCssFile() { + if (cssFile == null) { + File file = getJaxxFile(); + String extension = FileUtil.extension(file); + String fileName = file.getName(); + int length = fileName.length() - extension.length(); + String identCssFilename = fileName.substring(0, length) + "css"; + cssFile = new File(file.getParentFile(), identCssFilename); + } + return cssFile; + } + + public String getClassName() { + if (className == null) { + + className = relativePath.substring(0, relativePath.lastIndexOf(".")); + className = className.replace(File.separatorChar, '.'); + className = className.replace('/', '.'); + className = className.replace('\\', '.'); + className = className.replace(':', '.'); + + } + return className; + } + + public void clear() { + if (compiler != null) { + compiler.clear(); + } + } + +// public void setSymbolTable(SymbolTable symbolTable) { +// this.symbolTable = symbolTable; +// } + + public void setCompiler(JAXXCompiler compiler) { + this.compiler = compiler; + } +} Property changes on: trunk/jaxx-compiler/src/main/java/jaxx/compiler/JAXXCompilerFile.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Modified: trunk/jaxx-compiler/src/main/java/jaxx/compiler/JAXXEngine.java =================================================================== --- trunk/jaxx-compiler/src/main/java/jaxx/compiler/JAXXEngine.java 2010-05-02 11:04:42 UTC (rev 1864) +++ trunk/jaxx-compiler/src/main/java/jaxx/compiler/JAXXEngine.java 2010-05-02 16:55:27 UTC (rev 1865) @@ -25,499 +25,195 @@ package jaxx.compiler; -import jaxx.compiler.java.JavaFileGenerator; -import jaxx.compiler.spi.Initializer; +import jaxx.compiler.tasks.CompileFirstPassTask; +import jaxx.compiler.tasks.CompileSecondPassTask; +import jaxx.compiler.tasks.FinalizeTask; +import jaxx.compiler.tasks.GenerateTask; +import jaxx.compiler.tasks.InitTask; +import jaxx.compiler.tasks.JAXXEngineTask; +import jaxx.compiler.tasks.ProfileTask; +import jaxx.compiler.tasks.StyleSheetTask; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.nuiton.util.StringUtil; import java.io.File; import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; /** + * The engine to compile jaxx files. + * <p/> + * The method {@link #run()} launch the compilation of files. + * * @author tchemit <chemit@codelutin.com> * @since 2.0.0 was previously JAXXCompilerLaunchor */ public class JAXXEngine { - /** - * Logger - */ + /** Logger */ private static final Log log = LogFactory.getLog(JAXXEngine.class); - public void addJaxxFileClassName(String className) { - jaxxFileClassNames.add(className); - } + /** configuration of the launchor and underlines compilers */ + protected final CompilerConfiguration configuration; - public void addJaxxFile(File jaxxFile) { - jaxxFiles.add(jaxxFile); - } + /** original list of files to run */ + protected final JAXXCompilerFile[] incomingFiles; - public boolean containsJaxxFileClassName(String className) { - return jaxxFileClassNames.contains(className); - } + /** Files to be treated while compilation. */ + protected final List<JAXXCompilerFile> compilingFiles; - public LifeCycle getCurrentPass() { - return currentPass; - } - /** shared instance of unique launchor at a givne time. */ - protected static JAXXEngine singleton; + /** Warnings detected while running. */ + protected final List<String> warnings; - /** - * Create a new empty launchor and set it as current launchor accessible via method {@link #get()} - * - * @return the new instanciated launchor - */ - public static synchronized JAXXEngine newLaunchor() { - return newLaunchor((File[]) null, null, null); - } + /** Errors detected while running. */ + protected final List<String> errors; - /** - * Create a new launchor and set it as current launchor accessible via method {@link #get()}. - * <p/> - * The launchor will be prepared to run 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 configuration the compiler configuration to use - * @return the new instanciated launchor - */ - public static synchronized JAXXEngine newLaunchor(File base, String[] relativePaths, CompilerConfiguration configuration) { - 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(':', '.'); - } - return newLaunchor(files, classNames, configuration); - } + /** tasks to launch */ + protected JAXXEngineTask[] tasks; - /** - * Create a new launchor and set it as current launchor accessible via method {@link #get()}. - * <p/> - * The launchor will be prepared to run 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 run - * @param classNames the names of the classes being compiled - * @param configuration the compiler configuration to use - * @return the new instanciated launchor - */ - public static synchronized JAXXEngine newLaunchor(File[] files, String[] classNames, CompilerConfiguration configuration) { - if (singleton != null) { - singleton.reset(); - } - singleton = new JAXXEngine(files, classNames, configuration); - return singleton; - } + /** current pass of the engine */ + protected JAXXEngineTask currentTask; - /** - * @return the current launchor - * @throws NullPointerException if no launchor was registred via a <code>newLaunchor-like</code> method. - */ - public static JAXXEngine 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 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(); - } - } - /** - * configuration of the launchor and underlines compilers - */ - protected CompilerConfiguration configuration; - /** - * original list of files to run - */ - protected final File[] files; - /** - * original list of classes to run - */ - protected final String[] classNames; - /** - * Files to be treated while compilation. - */ - private List<File> jaxxFiles = new ArrayList<File>(); - /** - * Class names corresponding to the files in the jaxxFiles list. - */ - private List<String> jaxxFileClassNames = new ArrayList<String>(); - /** - * Maps the names of classes being compiled to the compiler instance handling the compilation. - */ - protected Map<String, JAXXCompiler> compilers = new HashMap<String, JAXXCompiler>(); - /** - * 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>(); - /** - * current pass of the engine - */ - private LifeCycle currentPass; - /** - * Warnings detected while running. - */ - protected List<String> warnings = new ArrayList<String>(); - /** - * Errors detected while running. - */ - protected List<String> errors = new ArrayList<String>(); - /** - * profile attached to the engine (can be null) - */ + /** profile attached to the engine (can be null) */ protected JAXXProfile profiler; - /** - * decorators available in engine - */ - protected Map<String, CompiledObjectDecorator> decorators; - /** - * finalizers available in engine - */ - protected List<JAXXCompilerFinalizer> finalizers; - /** - * Different passes of the engine. - * - * Each pass defines the {@link #run(JAXXEngine)} method which implements - * the logic of the pass. - */ - protected enum LifeCycle { + protected JAXXEngine(CompilerConfiguration configuration, + File base, + String... relativePaths) { - /** - * state before compilation - */ - init { + if (configuration == null) { - @Override - public boolean run(JAXXEngine engine) { - boolean success = true; - engine.warnings.clear(); - engine.errors.clear(); - // init decorators - if (engine.decorators == null) { - engine.decorators = new TreeMap<String, CompiledObjectDecorator>(); - // load decorators - for (CompiledObjectDecorator decorator : ServiceLoader.load(CompiledObjectDecorator.class)) { - engine.decorators.put(decorator.getName(), decorator); - } - } - // init finalizers - engine.finalizers = new ArrayList<JAXXCompilerFinalizer>(); - for (JAXXCompilerFinalizer finalizer : ServiceLoader.load(JAXXCompilerFinalizer.class)) { - engine.finalizers.add(finalizer); - } + // use a default configuration + configuration = new DefaultCompilerConfiguration(); + } - engine.jaxxFiles.addAll(Arrays.asList(engine.files)); - engine.jaxxFileClassNames.addAll(Arrays.asList(engine.classNames)); - return success; - } - }, - /** - * first pass of compilation - */ - compile_first_pass { + this.configuration = configuration; + warnings = new ArrayList<String>(); + errors = new ArrayList<String>(); + compilingFiles = new ArrayList<JAXXCompilerFile>(); - @Override - public boolean run(JAXXEngine engine) throws Exception { - boolean success = true; - boolean compiled; - do { - compiled = false; - assert engine.jaxxFiles.size() == engine.jaxxFileClassNames.size(); - Iterator<File> filesIterator = new ArrayList<File>(engine.jaxxFiles).iterator(); // clone it so it can safely be modified while we're iterating - Iterator<String> classNamesIterator = new ArrayList<String>(engine.jaxxFileClassNames).iterator(); - while (filesIterator.hasNext()) { - File file = filesIterator.next(); - String className = classNamesIterator.next(); - if (log.isDebugEnabled()) { - log.debug("compile first pass for " + className); - } - if (engine.symbolTables.get(file) == null) { - compiled = true; - if (engine.compilers.containsKey(className)) { - throw new CompilerException("Internal error: " + className + " is already being compiled, attempting to compile it again"); - } + // add all default files to compile + for (String relativePath : relativePaths) { + JAXXCompilerFile compilerFile = + new JAXXCompilerFile(base, new File(base, relativePath)); + addFileToCompile(compilerFile); + } - File destDir = engine.configuration.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; - } - } - JAXXCompiler compiler = engine.newCompiler(file.getParentFile(), file, className); - addStartProfileTime(engine, compiler); - engine.compilers.put(className, compiler); - compiler.compileFirstPass(); - if (compiler.getConfiguration().isAutoImportCss() && !compiler.isIdentCssFound()) { + incomingFiles = getCompilingFiles(); + } - // check if can add ident css file + public JAXXEngineTask[] getTasks() { + if (tasks == null) { + List<JAXXEngineTask> tasks = new ArrayList<JAXXEngineTask>(); - File cssFile = compiler.getIdentCssFile(); - if (log.isDebugEnabled()) { - log.debug("test ident css file " + cssFile+" : "+compiler.getConfiguration().isVerbose()); - } - if (cssFile.exists()) { + tasks.add(new InitTask()); + tasks.add(new CompileFirstPassTask()); + tasks.add(new CompileSecondPassTask()); + tasks.add(new StyleSheetTask()); + tasks.add(new FinalizeTask()); + tasks.add(new GenerateTask()); - compiler.identCssFound = true; - - if (compiler.getConfiguration().isVerbose()) { - log.info("Auto import of css " + cssFile); - } - // ok add it - compiler.registerStyleSheetFile(cssFile); - } - } - addEndProfileTime(engine, compiler); - assert !engine.symbolTables.values().contains(compiler.getSymbolTable()) : "symbolTable is already registered"; - engine.symbolTables.put(file, compiler.getSymbolTable()); - if (compiler.isFailed()) { - success = false; - } - } - } - - } while (compiled); - return success; + if (getConfiguration().isProfile()) { + tasks.add(new ProfileTask()); } - }, - /** - * second pass of compilation - */ - compile_second_pass { - @Override - public boolean run(JAXXEngine engine) throws Exception { - boolean success = true; - List<File> jaxxFilesClone = new ArrayList<File>(engine.jaxxFiles); - for (String className : engine.jaxxFileClassNames) { - JAXXCompiler compiler = engine.getCompiler(className, "Internal error: could not find compiler for " + className + " during second pass"); - addStartProfileTime(engine, compiler); - if (log.isDebugEnabled()) { - log.debug("runInitializers for " + className); - } - if (!compiler.isFailed()) { - compiler.runInitializers(); - } - if (log.isDebugEnabled()) { - log.debug("compile second pass for " + className); - } - compiler.compileSecondPass(); - addEndProfileTime(engine, compiler); - if (log.isDebugEnabled()) { - log.debug("done with result [" + !compiler.isFailed() + "] for " + className); - } - if (compiler.isFailed()) { - success = false; - } - } - if (!jaxxFilesClone.equals(engine.jaxxFiles)) { - throw new AssertionError("Internal error: compilation set altered during pass 2 (was " + jaxxFilesClone + ", modified to " + engine.jaxxFiles + ")"); - } - return success; - } - }, - /** - * applying stylesheet - */ - stylesheet_pass { + this.tasks = tasks.toArray(new JAXXEngineTask[tasks.size()]); + } + return tasks; + } - @Override - public boolean run(JAXXEngine engine) throws Exception { - boolean success = true; - for (String className : engine.jaxxFileClassNames) { - JAXXCompiler compiler = engine.getCompiler(className, "Internal error: could not find compiler for " + className + " during stylesheet application"); - addStartProfileTime(engine, compiler); - compiler.applyStylesheets(); - addEndProfileTime(engine, compiler); - if (compiler.isFailed()) { - success = false; - } - } - return success; - } - }, - /** - * finalize compiler - */ - finalize_compiler { + /** @return the errors of the engine */ + public List<String> getErrors() { + return errors; + } - @Override - public boolean run(JAXXEngine engine) throws Exception { - boolean success = true; - for (String className : engine.jaxxFileClassNames) { - JAXXCompiler compiler = engine.getCompiler(className, "Internal error: could not find compiler for " + className + " during code generation"); - addStartProfileTime(engine, compiler); - compiler.finalizeCompiler(engine.finalizers); - addEndProfileTime(engine, compiler); - if (compiler.isFailed()) { - success = false; - } - } - return success; - } - }, - /** - * generate java file - */ - generate_pass { + /** @return the warnings of the engine */ + public List<String> getWarnings() { + return warnings; + } - @Override - public boolean run(JAXXEngine engine) throws Exception { - boolean success = true; - JavaFileGenerator generator = new JavaFileGenerator(JAXXCompiler.getLineSeparator(), engine.configuration.isVerbose()); + public JAXXProfile getProfiler() { + if (profiler == null && getConfiguration().isProfile()) { + profiler = new JAXXProfile(); + } + return profiler; + } - for (String className : engine.jaxxFileClassNames) { - JAXXCompiler compiler = engine.getCompiler(className, "Internal error: could not find compiler for " + className + " during code generation"); - addStartProfileTime(engine, compiler); - compiler.generate(generator); - addEndProfileTime(engine, compiler); - if (compiler.isFailed()) { - success = false; - } - } - return success; - } - }, - /** - * display profile results - */ - profile_pass { + public CompilerConfiguration getConfiguration() { + return configuration; + } - @Override - public boolean run(JAXXEngine engine) throws Exception { - boolean success = true; - if (engine.configuration.isProfile()) { - StringBuilder buffer = engine.profiler.computeProfileReport(); - log.info(buffer.toString()); - } - return success; - } - }; + public JAXXCompilerFile[] getIncomingFiles() { + return incomingFiles; + } - /** - * Run the pass. - * - * @param engine the engine to use - * @return {@code true} if pass was ok, {@code false} otherwise - * @throws Exception if any pb - */ - public abstract boolean run(JAXXEngine engine) throws Exception; + public JAXXCompilerFile[] getCompilingFiles() { + return compilingFiles.toArray( + new JAXXCompilerFile[compilingFiles.size()]); + } - void addStartProfileTime(JAXXEngine engine, JAXXCompiler compiler) { - engine.addProfileTime(compiler, name() + "_start"); + public boolean containsJaxxFileClassName(String className) { + for (JAXXCompilerFile file : getCompilingFiles()) { + if (className.equals(file.getClassName())) { + return true; + } } - - void addEndProfileTime(JAXXEngine engine, JAXXCompiler compiler) { - engine.addProfileTime(compiler, name() + "_end"); - } + return false; } - protected JAXXEngine(File[] files, String[] classNames, CompilerConfiguration options) { - this.configuration = options == null ? new DefaultCompilerConfiguration() : options; - this.files = files; - this.classNames = classNames; - if (log.isDebugEnabled()) { - log.debug("files : " + Arrays.toString(files)); - } - if (this.configuration.isProfile()) { - profiler = new JAXXProfile(); - } + public boolean isFirstCompilePassTask() { + return currentTask != null && + CompileFirstPassTask.TASK_NAME.equals(currentTask.getName()); } - /** - * Resets all state in preparation for a new compilation session. - */ + /** Resets all state in preparation for a new compilation session. */ protected void reset() { - jaxxFiles.clear(); - jaxxFileClassNames.clear(); - symbolTables.clear(); - for (JAXXCompiler jaxxCompiler : compilers.values()) { - jaxxCompiler.clear(); + for (JAXXCompilerFile compilerFile : compilingFiles) { + compilerFile.clear(); } - compilers.clear(); + compilingFiles.clear(); if (profiler != null) { profiler.clear(); profiler = null; } - if (decorators != null) { - decorators.clear(); - decorators = null; - } - if (finalizers != null) { - finalizers.clear(); - finalizers = null; - } + clearReports(); } - public String getVersion() { - return "2.0.0"; + public void clearReports() { + getWarnings().clear(); + getErrors().clear(); } - /** - * Creates a dummy Compiler for use in unit testing or dettached use of an - * engine. - * - * @param classLoader class loader to use - * @return the compiler - */ - public static JAXXCompiler createDummyCompiler(final ClassLoader classLoader) { - JAXXCompiler compiler = new JAXXCompiler(null, null, null, null, null, null); - compiler.classLoader = classLoader; - return compiler; + public String getVersion() { + return "2.0.2"; } /** * Obtain the jaxx compiler of the given class name. - * + * * @param className the name of the class to use - * @return the compiler instance which is processing the specified JAXX class. Each class is compiled by a - * different compiler instance. + * @return the compiler instance which is processing the specified JAXX class. + * Each class is compiled by a different compiler instance. */ public JAXXCompiler getJAXXCompiler(String className) { - return compilers == null ? null : compilers.get(className); + for (JAXXCompilerFile compilingFile : compilingFiles) { + if (className.equals(compilingFile.getClassName())) { + return compilingFile.getCompiler(); + } + } + return null; } /** * Obtain the symbo table for the given class name. * * @param className the name of the class to use - * @return the symbol table for the specified JAXX class. Must be called during the second compiler pass. + * @return the symbol table for the specified JAXX class. + * Must be called during the second compiler pass. * Returns <code>null</code> if no such symbol table could be found. */ public SymbolTable getSymbolTable(String className) { @@ -535,10 +231,15 @@ * @return the decorator found. * @throws IllegalArgumentException if decorator not found for the given name. */ - public CompiledObjectDecorator getDecorator(String name) throws IllegalArgumentException { + public CompiledObjectDecorator getDecorator(String name) + throws IllegalArgumentException { + Map<String, CompiledObjectDecorator> decorators = + getConfiguration().getDecorators(); CompiledObjectDecorator decorator = decorators.get(name); if (decorator == null) { - throw new IllegalArgumentException("could not find decorator with key " + name + " (known decorators : " + decorators.keySet() + ")"); + throw new IllegalArgumentException( + "could not find decorator with key " + name + + " (known decorators : " + decorators.keySet() + ")"); } return decorator; } @@ -550,8 +251,10 @@ * @return the decorator found */ public CompiledObjectDecorator getDecorator(Class<?> type) { + Map<String, CompiledObjectDecorator> decorators = + getConfiguration().getDecorators(); for (CompiledObjectDecorator decorator : decorators.values()) { - if (type == decorator.getClass()) { + if (decorator.getClass().equals(type)) { return decorator; } } @@ -577,51 +280,42 @@ } /** - * @return the errors of the engine - */ - public List<String> getErrors() { - return errors; - } - - /** - * @return the warnings of the engine - */ - public List<String> getWarnings() { - return warnings; - } - - /** * Compiled a set of files. * * @return {@code -1} if errors appears, the number of generated files - * otherwise. + * otherwise. */ - public synchronized int run() { + public int run() { try { boolean success = true; - for (LifeCycle state : LifeCycle.values()) { + for (JAXXEngineTask task : getTasks()) { if (!success) { // stop as soon as a engine phase failed break; } - currentPass = state; - if (configuration.isVerbose()) { - log.info("'" + state + "' on " + jaxxFiles.size() + " file(s)"); + + currentTask = task; + long t0 = System.nanoTime(); + if (isVerbose()) { + log.info("Start task '" + task.getName() + "' on " + + compilingFiles.size() + " file(s)"); } - success = state.run(this); + success = task.perform(this); + if (isVerbose()) { + log.info("task '" + task.getName() + "' done in " + + StringUtil.convertTime(System.nanoTime() - t0) + ); + } } - return success ? compilers.size() : -1; + return success ? compilingFiles.size() : -1; //FIXME : deal better the exception treatment... } catch (CompilerException e) { - log.error(e.getMessage(),e); -// System.err.println(e.getMessage()); -// e.printStackTrace(); + log.error(e.getMessage(), e); return -1; } catch (Throwable e) { - log.error(e.getMessage(),e); -// e.printStackTrace(); + log.error(e.getMessage(), e); return -1; } finally { //TC - 20081018 only reset when no error was detected @@ -632,67 +326,94 @@ } /** - * Obtain the compiler for the given class name. - * - * @param className the class name of the searched compiler - * @param message the message to throw if compiler not found - * @return the compiler found - * @throws CompilerException if compiler not found + * Adds a {@code file} to be compiled. + * + * @param file the {@link JAXXCompilerFile} to add. */ - protected JAXXCompiler getCompiler(String className, String message) throws CompilerException { - JAXXCompiler compiler = compilers.get(className); - if (compiler == null) { - throw new CompilerException(message); + public void addFileToCompile(JAXXCompilerFile file) { + + if (isVerbose()) { + log.info("register jaxx file " + file.getJaxxFile()); } - return compiler; + compilingFiles.add(file); } /** - * Create a new compiler. + * Adds a {@link JAXXCompilerFile} given the jaxx file and the + * corresponding class fully qualified name. * - * @param parentFile the directory where to generate the java file - * @param file the path of file to generate - * @param className name of the class to generate in the file + * @param jaxxFile the jaxx file location + * @param jaxxClassName the fully qualified name of the jaxx class + */ + public void addFileToCompile(File jaxxFile, String jaxxClassName) { + + if (isVerbose()) { + log.info("file = " + jaxxFile + ", fqn = " + jaxxClassName); + } + + JAXXCompilerFile file = new JAXXCompilerFile(jaxxFile, jaxxClassName); + addFileToCompile(file); + } + + /** + * Create a new compiler and attach it to the given {@code jaxxFile}. + * + * @param jaxxFile the definition of jaxx file to compile * @return the new compiler - * @throws InvocationTargetException introspection error - * @throws IllegalAccessException introspection error - * @throws InstantiationException introspection error - * @throws NoSuchMethodException introspection error + * @throws Exception if any pb while creation of compiler */ - protected JAXXCompiler newCompiler(File parentFile, File file, String className) throws InvocationTargetException, IllegalAccessException, InstantiationException, NoSuchMethodException { - Constructor<? extends JAXXCompiler> cons = configuration.getCompilerClass().getConstructor(JAXXEngine.class, File.class, File.class, String.class, CompilerConfiguration.class, List.class); - return cons.newInstance(this, parentFile, file, className, configuration, - Arrays.asList("java.awt.*", - "java.awt.event.*", -// "java.beans.*", - "java.io.*", - "java.lang.*", - "java.util.*", - "javax.swing.*", - "javax.swing.border.*", - "javax.swing.event.*", -// "jaxx.runtime.swing.JAXXButtonGroup", -// "jaxx.runtime.swing.HBox", -// "jaxx.runtime.swing.VBox", -// "jaxx.runtime.swing.Table", - "jaxx.runtime.*", - "jaxx.runtime.swing.*", -// "jaxx.runtime.JAXXUtil", -// "jaxx.runtime.SwingUtil", - "static org.nuiton.i18n.I18n._", - "static jaxx.runtime.SwingUtil.createImageIcon") - ); + public JAXXCompiler newCompiler(JAXXCompilerFile jaxxFile) throws Exception { + + Class<?> compilerClass = + getConfiguration().getCompilerClass(); + + if (compilerClass == null) { + throw new NullPointerException( + "Configuration compilerClass is null"); + } + + Constructor<?> cons = compilerClass.getConstructor( + JAXXEngine.class, + JAXXCompilerFile.class, + List.class + ); + + JAXXCompiler jaxxCompiler = (JAXXCompiler) cons.newInstance( + this, + jaxxFile, + Arrays.asList( + "java.awt.*", + "java.awt.event.*", + "java.io.*", + "java.lang.*", + "java.util.*", + "javax.swing.*", + "javax.swing.border.*", + "javax.swing.event.*", + "jaxx.runtime.*", + "jaxx.runtime.swing.*", + "static org.nuiton.i18n.I18n._", + "static jaxx.runtime.SwingUtil.createImageIcon" + ) + ); + jaxxFile.setCompiler(jaxxCompiler); + return jaxxCompiler; } + public boolean isVerbose() { + return getConfiguration().isVerbose(); + } + /** * Add a profile time for the given compiler and key. - * + * <p/> * Note: if {@link #profiler} is {@code null}, do nothing * * @param compiler the compiler to profile - * @param key the key of profiling + * @param key the key of profiling */ public void addProfileTime(JAXXCompiler compiler, String key) { + JAXXProfile profiler = getProfiler(); if (profiler != null) { profiler.addTime(compiler, key); } Added: trunk/jaxx-compiler/src/main/java/jaxx/compiler/JAXXFactory.java =================================================================== --- trunk/jaxx-compiler/src/main/java/jaxx/compiler/JAXXFactory.java (rev 0) +++ trunk/jaxx-compiler/src/main/java/jaxx/compiler/JAXXFactory.java 2010-05-02 16:55:27 UTC (rev 1865) @@ -0,0 +1,158 @@ +/* + * #%L + * JAXX :: Compiler + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2008 - 2010 CodeLutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ +package jaxx.compiler; + +import jaxx.compiler.spi.Initializer; +import jaxx.compiler.tags.TagManager; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import java.io.File; +import java.util.ServiceLoader; + +/** + * Factory of {@link JAXXCompiler} and {@link JAXXEngine}. + * + * @author tchemit <chemit@codelutin.com> + * @since 2.0.2 + */ +public class JAXXFactory { + + /** Logger */ + private static final Log log = LogFactory.getLog(JAXXFactory.class); + + /** shared instance of engine. */ + protected static JAXXEngine engine; + + /** shared instance of configuration * */ + protected static CompilerConfiguration configuration; + + protected JAXXFactory() { + // no instance + } + + public static void setConfiguration(CompilerConfiguration configuration) { + JAXXFactory.configuration = configuration; + } + + /** + * Create a new empty launchor and set it as current launchor accessible + * via method {@link #getEngine()}. + * + * @return the new instanciated launchor + */ + public static JAXXEngine newDummyEngine() { + return newEngine(null); + } + + /** + * Create a new launchor and set it as current launchor accessible via + * method {@link #getEngine()}. + * <p/> + * The launchor will be prepared to run 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 basedir the directory against which to resolve relative paths + * @param relativePaths a list of relative paths to .jaxx files being compiled + * @return the new instanciated launchor + */ + public static JAXXEngine newEngine(File basedir, String... relativePaths) { + checkConfiguration(); + if (engine != null) { + engine.reset(); + } + engine = new JAXXEngine(configuration, basedir, relativePaths); + return engine; + } + + /** + * Creates a dummy Compiler for use in unit testing or dettached use of an + * engine. + * + * @param classLoader class loader to use + * @return the compiler + */ + public static JAXXCompiler newDummyCompiler(ClassLoader classLoader) { + JAXXCompiler compiler = new JAXXCompiler(); + compiler.setClassLoader(classLoader); + return compiler; + } + + /** + * @return the current launchor + * @throws NullPointerException if no launchor was registred via a + * <code>newEngine-like</code> method. + */ + public static JAXXEngine getEngine() throws NullPointerException { + checkConfiguration(); + checkEngine(); + return engine; + } + + /** + * @return <code> if there is an engine registred, + * <code>false</code> otherwise. + */ + public static boolean isEngineRegistred() { + return engine != null; + } + + /** + * Load the {@link Initializer} services found via the{@link ServiceLoader} + * mecanism. + */ + public static void initFactory() { + + // must have a configuration + checkConfiguration(); + + TagManager.reset(); + + boolean verbose = configuration.isVerbose(); + for (Initializer initializer : + configuration.getInitializers().values()) { + if (verbose) { + log.info("load initializer " + initializer); + } + initializer.initialize(); + } + + } + + protected static void checkConfiguration() throws NullPointerException { + if (configuration == null) { + throw new NullPointerException("No configuration was registred."); + } + } + + protected static void checkEngine() throws NullPointerException { + if (engine == null) { + throw new NullPointerException("No engine was registred."); + } + } +} Property changes on: trunk/jaxx-compiler/src/main/java/jaxx/compiler/JAXXFactory.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Modified: trunk/jaxx-compiler/src/main/java/jaxx/compiler/JAXXProfile.java =================================================================== --- trunk/jaxx-compiler/src/main/java/jaxx/compiler/JAXXProfile.java 2010-05-02 11:04:42 UTC (rev 1864) +++ trunk/jaxx-compiler/src/main/java/jaxx/compiler/JAXXProfile.java 2010-05-02 16:55:27 UTC (rev 1865) @@ -25,13 +25,22 @@ package jaxx.compiler; +import jaxx.compiler.tasks.CompileFirstPassTask; +import jaxx.compiler.tasks.CompileSecondPassTask; +import jaxx.compiler.tasks.FinalizeTask; +import jaxx.compiler.tasks.GenerateTask; +import jaxx.compiler.tasks.StyleSheetTask; +import org.nuiton.util.StringUtil; + +import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.SortedMap; -import jaxx.compiler.JAXXEngine.LifeCycle; -import org.nuiton.util.StringUtil; +import java.util.TreeMap; /** * Pour profiler les temps d'execution pendant une compilation. @@ -49,24 +58,27 @@ protected class CompilerEntry { JAXXCompiler compiler; + SortedMap<String, Long> times; public CompilerEntry(JAXXCompiler compiler) { this.compiler = compiler; - times = new java.util.TreeMap<String, Long>(); + times = new TreeMap<String, Long>(); } } public static class ProfileResult { long min, max, average, total; + Map<JAXXCompiler, Long> delta; + List<Long> times; - ProfileResult(String label, Map<JAXXCompiler, Long> delta) { + ProfileResult(Map<JAXXCompiler, Long> delta) { this.delta = delta; - times = new java.util.ArrayList<Long>(delta.values()); - java.util.Collections.sort(times); + times = new ArrayList<Long>(delta.values()); + Collections.sort(times); min = times.get(0); max = times.get(times.size() - 1); total = 0; @@ -100,12 +112,14 @@ throw new IllegalArgumentException("could not find compiler for time " + l); } } + SortedMap<Integer, CompilerEntry> entries; + List<JAXXCompiler> compilers; public JAXXProfile() { - compilers = new java.util.ArrayList<JAXXCompiler>(); - entries = new java.util.TreeMap<Integer, CompilerEntry>(); + compilers = new ArrayList<JAXXCompiler>(); + entries = new TreeMap<Integer, CompilerEntry>(); } public void addTime(JAXXCompiler compiler, String key) { @@ -113,18 +127,22 @@ e.times.put(key, System.nanoTime()); } - public Map<JAXXCompiler, Long> getDelta(String label, String keyOne, String keyTwo) { - Map<JAXXCompiler, Long> result = new java.util.HashMap<JAXXCompiler, Long>(); - for (java.util.Map.Entry<Integer, CompilerEntry> e : entries.entrySet()) { + public Map<JAXXCompiler, Long> getDelta(String keyOne, String keyTwo) { + Map<JAXXCompiler, Long> result = new HashMap<JAXXCompiler, Long>(); + for (Map.Entry<Integer, CompilerEntry> e : entries.entrySet()) { JAXXCompiler c = getCompiler(e.getKey()); CompilerEntry entry = e.getValue(); Long t0 = entry.times.get(keyOne); Long t1 = entry.times.get(keyTwo); if (t0 == null) { - throw new NullPointerException("could not find time for " + keyOne + " on compiler " + c.getOutputClassName()); + throw new NullPointerException( + "could not find time for " + keyOne + + " on compiler " + c.getOutputClassName()); } if (t1 == null) { - throw new NullPointerException("could not find time for " + keyTwo + " on compiler " + c.getOutputClassName()); + throw new NullPointerException( + "could not find time for " + keyTwo + + " on compiler " + c.getOutputClassName()); } long delta = t1 - t0; result.put(c, delta); @@ -132,17 +150,17 @@ return result; } - public ProfileResult newProfileResult(LifeCycle step) { + public ProfileResult newProfileResult(String name) { ProfileResult result; - String name = step.name(); - Map<JAXXCompiler, Long> delta = getDelta(name, name + "_start", name + "_end"); - result = new ProfileResult(name, delta); + Map<JAXXCompiler, Long> delta = + getDelta(name + "_start", name + "_end"); + result = new ProfileResult(delta); return result; } public ProfileResult newProfileResult(ProfileResult... toCumul) { ProfileResult result; - Map<JAXXCompiler, Long> delta = new java.util.HashMap<JAXXCompiler, Long>(); + Map<JAXXCompiler, Long> delta = new HashMap<JAXXCompiler, Long>(); for (JAXXCompiler c : compilers) { long total = 0; for (ProfileResult cumul : toCumul) { @@ -151,7 +169,7 @@ } delta.put(c, total); } - result = new ProfileResult("all", delta); + result = new ProfileResult(delta); return result; } @@ -172,50 +190,102 @@ } } - ProfileResult cfp = newProfileResult(LifeCycle.compile_first_pass); - ProfileResult csp = newProfileResult(LifeCycle.compile_second_pass); - ProfileResult ssp = newProfileResult(LifeCycle.stylesheet_pass); - ProfileResult fp = newProfileResult(LifeCycle.finalize_compiler); - ProfileResult gp = newProfileResult(LifeCycle.generate_pass); - ProfileResult total = newProfileResult(cfp, csp, ssp,fp, gp); + ProfileResult cfp = newProfileResult(CompileFirstPassTask.TASK_NAME); + ProfileResult csp = newProfileResult(CompileSecondPassTask.TASK_NAME); + ProfileResult ssp = newProfileResult(StyleSheetTask.TASK_NAME); + ProfileResult fp = newProfileResult(FinalizeTask.TASK_NAME); + ProfileResult gp = newProfileResult(GenerateTask.TASK_NAME); + ProfileResult total = newProfileResult(cfp, csp, ssp, fp, gp); - String reportPattern = "\n|%1$-" + maxLength + "s|%2$15s|%3$15s|%4$15s|%5$15s|%6$15s|%7$15s|"; + String reportPattern = "\n|%1$-" + maxLength + + "s|%2$15s|%3$15s|%4$15s|%5$15s|%6$15s|%7$15s|"; char[] tmpC = new char[maxLength]; Arrays.fill(tmpC, '-'); String line = String.format(reportPattern, - new String(tmpC), - "---------------", - "---------------", - "---------------", - "---------------", - "---------------", - "---------------"); + new String(tmpC), + "---------------", + "---------------", + "---------------", + "---------------", + "---------------", + "---------------"); buffer.append(line); buffer.append(String.format(reportPattern, - "(files / stats) \\ passes", - "compile round 1", "compile round 2", "stylesheet", "finalize", "generation", "all passes")); + "(files / stats) \\ passes", + "compile round 1", + "compile round 2", + "stylesheet", + "finalize", + "generation", + "all passes") + ); buffer.append(line); // affiche les temps de tous les fichiers en temp total croissant for (Long l : total.times) { JAXXCompiler c = total.getCompiler(l); - printReportLine(buffer, reportPattern, c.getOutputClassName(), cfp.getTime(c), csp.getTime(c), ssp.getTime(c), fp.getTime(c), gp.getTime(c), total.getTime(c)); + printReportLine(buffer, + reportPattern, + c.getOutputClassName(), + cfp.getTime(c), + csp.getTime(c), + ssp.getTime(c), + fp.getTime(c), + gp.getTime(c), + total.getTime(c) + ); } buffer.append(line); if (compilers.size() > 1) { - printReportLine(buffer, reportPattern, "total (" + compilers.size() + " files)", cfp.total, csp.total, ssp.total, fp.total, gp.total, total.total); + printReportLine(buffer, + reportPattern, + "total (" + compilers.size() + " files)", + cfp.total, + csp.total, + ssp.total, + fp.total, + gp.total, + total.total + ); buffer.append(line); - printReportLine2(buffer, reportPattern, "min", cfp.min, csp.min, ssp.min, fp.min, gp.min, total.min); - printReportLine2(buffer, reportPattern, "max", cfp.max, csp.max, ssp.max, fp.max, gp.max, total.max); - printReportLine(buffer, reportPattern, "average", cfp.average, csp.average, ssp.average, fp.average, gp.average, total.average); + printReportLine2(buffer, + reportPattern, + "min", + cfp.min, + csp.min, + ssp.min, + fp.min, + gp.min, + total.min + ); + printReportLine2(buffer, + reportPattern, + "max", + cfp.max, + csp.max, + ssp.max, + fp.max, + gp.max, + total.max + ); + printReportLine(buffer, + reportPattern, + "average", + cfp.average, + csp.average, + ssp.average, + fp.average, + gp.average, + total.average + ); buffer.append(line); } cfp.clear(); @@ -226,25 +296,75 @@ return buffer; } + public static final String TIME_PATTERN = "%1$9s - %2$2d%%"; - protected void printReportLine(StringBuilder buffer, String reportPattern, String label, long firstPassCounter, long secondPassCounter, long cssCounter, long finalizeCounter, long generatorCounter, long totalCounter) { - float percentCFP = ((float) firstPassCounter / totalCounter) * 100; - float percentCSP = ((float) secondPassCounter / totalCounter) * 100; - float percentCSSP = ((float) cssCounter / totalCounter) * 100; - float percentFP = ((float) finalizeCounter / totalCounter) * 100; - float percentGP = ((float) generatorCounter / totalCounter) * 100; - String strCFP = String.format(TIME_PATTERN, StringUtil.convertTime(firstPassCounter), (int) percentCFP); - String strCSP = String.format(TIME_PATTERN, StringUtil.convertTime(secondPassCounter), (int) percentCSP); - String strCSSP = String.format(TIME_PATTERN, StringUtil.convertTime(cssCounter), (int) percentCSSP); - String strFP = String.format(TIME_PATTERN, StringUtil.convertTime(finalizeCounter), (int) percentFP); - String strGP = String.format(TIME_PATTERN, StringUtil.convertTime(generatorCounter), (int) percentGP); + protected void printReportLine(StringBuilder buffer, + String reportPattern, + String label, + long firstPassCounter, + long secondPassCounter, + long cssCounter, + long finalizeCounter, + long generatorCounter, + long totalCounter) { - buffer.append(String.format(reportPattern, label, strCFP, strCSP, strCSSP, strFP, strGP, StringUtil.convertTime(totalCounter))); + float percentCFP = (float) firstPassCounter / totalCounter * 100; + float percentCSP = (float) secondPassCounter / totalCounter * 100; + float percentCSSP = (float) cssCounter / totalCounter * 100; + float percentFP = (float) finalizeCounter / totalCounter * 100; + float percentGP = (float) generatorCounter / totalCounter * 100; + + String strCFP = String.format(TIME_PATTERN, + StringUtil.convertTime(firstPassCounter), + (int) percentCFP + ); + String strCSP = String.format(TIME_PATTERN, + StringUtil.convertTime(secondPassCounter), + (int) percentCSP + ); + String strCSSP = String.format(TIME_PATTERN, + StringUtil.convertTime(cssCounter), + (int) percentCSSP + ); + String strFP = String.format(TIME_PATTERN, + StringUtil.convertTime(finalizeCounter), + (int) percentFP + ); + String strGP = String.format(TIME_PATTERN, + StringUtil.convertTime(generatorCounter), + (int) percentGP + ); + + buffer.append(String.format(reportPattern, + label, + strCFP, + strCSP, + strCSSP, + strFP, + strGP, + StringUtil.convertTime(totalCounter)) + ); } - protected void printReportLine2(StringBuilder buffer, String reportPattern, String label, long firstPassCounter, long secondPassCounter, long cssCounter, long finalizeCounter, long generatorCounter, long totalCounter) { - buffer.append(String.format(reportPattern, label, StringUtil.convertTime(firstPassCounter), StringUtil.convertTime(secondPassCounter), StringUtil.convertTime(cssCounter), StringUtil.convertTime(finalizeCounter), StringUtil.convertTime(generatorCounter), StringUtil.convertTime(totalCounter))); + protected void printReportLine2(StringBuilder buffer, + String reportPattern, + String label, + long firstPassCounter, + long secondPassCounter, + long cssCounter, + long finalizeCounter, + long generatorCounter, + long totalCounter) { + buffer.append(String.format(reportPattern, + label, + StringUtil.convertTime(firstPassCounter), + StringUtil.convertTime(secondPassCounter), + StringUtil.convertTime(cssCounter), + StringUtil.convertTime(finalizeCounter), + StringUtil.convertTime(generatorCounter), + StringUtil.convertTime(totalCounter)) + ); } protected CompilerEntry getEntry(JAXXCompiler compiler) { Modified: trunk/jaxx-compiler/src/main/java/jaxx/compiler/SymbolTable.java =================================================================== --- trunk/jaxx-compiler/src/main/java/jaxx/compiler/SymbolTable.java 2010-05-02 11:04:42 UTC (rev 1864) +++ trunk/jaxx-compiler/src/main/java/jaxx/compiler/SymbolTable.java 2010-05-02 16:55:27 UTC (rev 1865) @@ -33,22 +33,22 @@ import java.util.List; import java.util.Map; -/** - * Symbol table constructed during the first pass of compilation. - */ +/** Symbol table constructed during the first pass of compilation. */ public class SymbolTable { private String superclass; // maps ID strings to class names -- we can't map directly to CompiledObjects, because we // can't create those until after the first pass + private Map<String, String> ids = new HashMap<String, String>(); + private List<FieldDescriptor> scriptFields = new ArrayList<FieldDescriptor>(); + private List<MethodDescriptor> scriptMethods = new ArrayList<MethodDescriptor>(); + private String[] interfaces; - /** - * @return the fully-qualified name of the superclass of the class described by this symbol table. - */ + /** @return the fully-qualified name of the superclass of the class described by this symbol table. */ public String getSuperclassName() { return superclass; } @@ -70,16 +70,12 @@ return ids; } - /** - * @return a list of <code>FieldDescriptors</code> for fields defined in <script> tags. - */ + /** @return a list of <code>FieldDescriptors</code> for fields defined in <script> tags. */ public List<FieldDescriptor> getScriptFields() { return scriptFields; } - /** - * @return a list of <code>MethodDescriptors</code> for methods defined in <script> tags. - */ + /** @return a list of <code>MethodDescriptors</code> for methods defined in <script> tags. */ public List<MethodDescriptor> getScriptMethods() { return scriptMethods; } @@ -87,4 +83,10 @@ public void setInterfaces(String[] interfaces) { this.interfaces = interfaces; } + + public void clear() { + ids.clear(); + scriptFields.clear(); + scriptMethods.clear(); + } } Modified: trunk/jaxx-compiler/src/main/java/jaxx/compiler/decorators/BoxedCompiledObjectDecorator.java =================================================================== --- trunk/jaxx-compiler/src/main/java/jaxx/compiler/decorators/BoxedCompiledObjectDecorator.java 2010-05-02 11:04:42 UTC (rev 1864) +++ trunk/jaxx-compiler/src/main/java/jaxx/compiler/decorators/BoxedCompiledObjectDecorator.java 2010-05-02 16:55:27 UTC (rev 1865) @@ -37,6 +37,7 @@ * * @author tchemit <chemit@codelutin.com> * @since 1.2 + * @plexus.component role-hint="boxed" role="jaxx.compiler.CompiledObjectDecorator" */ public class BoxedCompiledObjectDecorator extends DefaultCompiledObjectDecorator { Modified: trunk/jaxx-compiler/src/main/java/jaxx/compiler/decorators/DefaultCompiledObjectDecorator.java =================================================================== --- trunk/jaxx-compiler/src/main/java/jaxx/compiler/decorators/DefaultCompiledObjectDecorator.java 2010-05-02 11:04:42 UTC (rev 1864) +++ trunk/jaxx-compiler/src/main/java/jaxx/compiler/decorators/DefaultCompiledObjectDecorator.java 2010-05-02 16:55:27 UTC (rev 1865) @@ -38,10 +38,11 @@ import java.util.Map.Entry; /** - * The default compiledObjectDecorator. + * The default decorator to use on all compiled objects. * * @author tchemit <chemit@codelutin.com> * @since 1.2 + * @plexus.component role-hint="default" role="jaxx.compiler.CompiledObjectDecorator" */ public class DefaultCompiledObjectDecorator implements CompiledObjectDecorator { Modified: trunk/jaxx-compiler/src/main/java/jaxx/compiler/decorators/HelpRootCompiledObjectDecorator.java =================================================================== --- trunk/jaxx-compiler/src/main/java/jaxx/compiler/decorators/HelpRootCompiledObjectDecorator.java 2010-05-02 11:04:42 UTC (rev 1864) +++ trunk/jaxx-compiler/src/main/java/jaxx/compiler/decorators/HelpRootCompiledObjectDecorator.java 2010-05-02 16:55:27 UTC (rev 1865) @@ -43,6 +43,7 @@ * * @author tchemit <chemit@codelutin.com> * @since 1.2 + * @plexus.component role-hint="help" role="jaxx.compiler.CompiledObjectDecorator" */ public class HelpRootCompiledObjectDecorator extends DefaultCompiledObjectDecorator { Modified: trunk/jaxx-compiler/src/main/java/jaxx/compiler/finalizers/DefaultFinalizer.java =================================================================== --- trunk/jaxx-compiler/src/main/java/jaxx/compiler/finalizers/DefaultFinalizer.java 2010-05-02 11:04:42 UTC (rev 1864) +++ trunk/jaxx-compiler/src/main/java/jaxx/compiler/finalizers/DefaultFinalizer.java 2010-05-02 16:55:27 UTC (rev 1865) @@ -57,6 +57,7 @@ * {@link JAXXCompiler} now only deals with the compilation of files. * * @author tchemit <chemit@codelutin.com> + * @plexus.component role-hint="default" role="jaxx.compiler.JAXXCompilerFinalizer" */ public class DefaultFinalizer implements JAXXCompilerFinalizer { Modified: trunk/jaxx-compiler/src/main/java/jaxx/compiler/finalizers/SwingFinalizer.java =================================================================== --- trunk/jaxx-compiler/src/main/java/jaxx/compiler/finalizers/SwingFinalizer.java 2010-05-02 11:04:42 UTC (rev 1864) +++ trunk/jaxx-compiler/src/main/java/jaxx/compiler/finalizers/SwingFinalizer.java 2010-05-02 16:55:27 UTC (rev 1865) @@ -36,7 +36,10 @@ import java.lang.reflect.Modifier; -/** @author tchemit <chemit@codelutin.com> */ +/** + * @author tchemit <chemit@codelutin.com> + * @plexus.component role-hint="swing" role="jaxx.compiler.JAXXCompilerFinalizer" + */ public class SwingFinalizer implements JAXXCompilerFinalizer { @Override Modified: trunk/jaxx-compiler/src/main/java/jaxx/compiler/finalizers/ValidatorFinalizer.java =================================================================== --- trunk/jaxx-compiler/src/main/java/jaxx/compiler/finalizers/ValidatorFinalizer.java 2010-05-02 11:04:42 UTC (rev 1864) +++ trunk/jaxx-compiler/src/main/java/jaxx/compiler/finalizers/ValidatorFinalizer.java 2010-05-02 16:55:27 UTC (rev 1865) @@ -45,12 +45,21 @@ import java.util.List; /** + * To finalize validators fields. + * * @author tchemit <chemit@codelutin.com> + * @plexus.component role-hint="validators" role="jaxx.compiler.JAXXCompilerFinalizer" */ public class ValidatorFinalizer implements JAXXCompilerFinalizer { - protected static final JavaField VALIDATOR_IDS_FIELD = JavaFileGenerator.newField(Modifier.PROTECTED, - "java.util.List<String>", "validatorIds", true, "new ArrayList<String>()"); + protected static final JavaField VALIDATOR_IDS_FIELD = + JavaFileGenerator.newField( + Modifier.PROTECTED, + "java.util.List<String>", + "validatorIds", + true, + "new ArrayList<String>()" + ); @Override public boolean accept(JAXXCompiler compiler) { @@ -58,12 +67,12 @@ } @Override - public void finalizeCompiler(CompiledObject root, JAXXCompiler compiler, JavaFile javaFile, String packageName, String className) { + public void finalizeCompiler(CompiledObject root, + JAXXCompiler compiler, + JavaFile javaFile, + String packageName, + String className) { -// if (!BeanValidatorHandler.hasValidator(compiler)) { -// return; -// } - for (CompiledObject object : compiler.getObjects().values()) { List<ChildRef> childs = object.getChilds(); if (childs == null || childs.isEmpty()) { @@ -72,35 +81,56 @@ for (ChildRef child : childs) { String javaCode = child.getChildJavaCode(); // some validators are defined on this object - boolean found = BeanValidatorHandler.isComponentUsedByValidator(compiler, child.getChild().getId()); + boolean found = + BeanValidatorHandler.isComponentUsedByValidator( + compiler, + child.getChild().getId() + ); if (found) { // box the child component in a JxLayer - child.setChildJavaCode(SwingUtil.class.getSimpleName() + ".boxComponentWithJxLayer(" + javaCode + ")"); + child.setChildJavaCode( + SwingUtil.class.getSimpleName() + + ".boxComponentWithJxLayer(" + javaCode + ")"); } } } String eol = JAXXCompiler.getLineSeparator(); StringBuilder builder = new StringBuilder(); // register validator - List<CompiledBeanValidator> validators = BeanValidatorHandler.getValidators(compiler); - builder.append("// register ").append(validators.size()).append(" validator(s)").append(eol); + List<CompiledBeanValidator> validators = + BeanValidatorHandler.getValidators(compiler); + builder.append("// register "); + builder.append(validators.size()); + builder.append(" validator(s)"); + builder.append(eol); for (CompiledBeanValidator validator : validators) { String id = TypeManager.getJavaCode(validator.getId()); - builder.append("validatorIds.add(").append(id).append(");").append(eol); - builder.append("getValidator(").append(id).append(").installUIs();").append(eol); - builder.append("getValidator(").append(id).append(").reloadBean();").append(eol); - //compiler.appendLateInitializer("getValidator(" + id + ").validate();"); + builder.append("validatorIds.add("); + builder.append(id); + builder.append(");"); + builder.append(eol); + builder.append("getValidator("); + builder.append(id); + builder.append(").installUIs();"); + builder.append(eol); + builder.append("getValidator("); + builder.append(id); + builder.append(").reloadBean();"); + builder.append(eol); } - builder.append("validatorIds = java.util.Collections.unmodifiableList(validatorIds);").append(eol); + builder.append("validatorIds = java.util.Collections.unmodifiableList(validatorIds);"); + builder.append(eol); compiler.appendLateInitializer(builder.toString()); } @Override - public void prepareJavaFile(CompiledObject root, JAXXCompiler compiler, JavaFile javaFile, String packageName, String className) throws ClassNotFoundException { -// if (!BeanValidatorHandler.hasValidator(compiler)) { -// return; -// } - Class<?> validatorClass = compiler.getConfiguration().getValidatorClass(); + public void prepareJavaFile(CompiledObject root, + JAXXCompiler compiler, + JavaFile javaFile, + String packageName, + String className) throws ClassNotFoundException { + Class<?> validatorClass = + compiler.getConfiguration().getValidatorClass(); String validatorFQN = validatorClass.getName(); javaFile.addImport(validatorFQN); @@ -109,8 +139,12 @@ //TC-20091202 : pass this test if we want to interact with non generated code ? // if (javaFile.isSuperclassIsJAXXObject()) { - ClassDescriptor superClass = ClassDescriptorLoader.getClassDescriptor(javaFile.getSuperClass()); - boolean parentIsValidator = ClassDescriptorLoader.getClassDescriptor(validatorInterface).isAssignableFrom(superClass); + ClassDescriptor superClass = + ClassDescriptorLoader.getClassDescriptor(javaFile.getSuperClass()); + ClassDescriptor validatorInterfaceDescriptor = + ClassDescriptorLoader.getClassDescriptor(validatorInterface); + boolean parentIsValidator = + validatorInterfaceDescriptor.isAssignableFrom(superClass); if (parentIsValidator) { // nothing to generate (use the parent directly) @@ -129,6 +163,7 @@ "getValidator", "return (" + validatorFQN + "<?>) (validatorIds.contains(validatorId) ? getObjectById(validatorId) : null);", true, - new JavaArgument("String", "validatorId"))); + new JavaArgument("String", "validatorId")) + ); } } Modified: trunk/jaxx-compiler/src/main/java/jaxx/compiler/reflect/ClassDescriptorLoader.java =================================================================== --- trunk/jaxx-compiler/src/main/java/jaxx/compiler/reflect/ClassDescriptorLoader.java 2010-05-02 11:04:42 UTC (rev 1864) +++ trunk/jaxx-compiler/src/main/java/jaxx/compiler/reflect/ClassDescriptorLoader.java 2010-05-02 16:55:27 UTC (rev 1865) @@ -28,19 +28,30 @@ import jaxx.compiler.CompilerException; import jaxx.compiler.JAXXCompiler; import jaxx.compiler.JAXXEngine; +import jaxx.compiler.JAXXFactory; import jaxx.compiler.SymbolTable; import jaxx.runtime.JAXXObject; import jaxx.runtime.JAXXObjectDescriptor; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import java.io.*; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.net.URL; -import java.util.*; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; /** * Mirrors the class <code>java.lang.ClassLoader</code>. JAXX uses <code>ClassDescriptor</code> instead of <code>Class</code> @@ -49,101 +60,207 @@ * circular dependencies). */ public class ClassDescriptorLoader { - /** - * Logger - */ + + /** Logger */ private static final Log log = LogFactory.getLog(ClassDescriptorLoader.class); - private static Map<String, ClassDescriptor> descriptors = new HashMap<String, ClassDescriptor>(); + private static Map<String, ClassDescriptor> descriptors = + new HashMap<String, ClassDescriptor>(); private ClassDescriptorLoader() { + // on instance } - public static synchronized ClassDescriptor getClassDescriptor(String className) throws ClassNotFoundException { - return getClassDescriptor(className, Thread.currentThread().getContextClassLoader()); - //return getClassDescriptor(className, ClassDescriptorLoader.class.getClassLoader()); + public static ClassDescriptor getClassDescriptor( + String className) throws ClassNotFoundException { + + ClassDescriptor descriptor = getClassDescriptor( + className, + Thread.currentThread().getContextClassLoader() + ); + return descriptor; } - public static synchronized ClassDescriptor getClassDescriptor(String className, ClassLoader classLoader) throws ClassNotFoundException { + public static ClassDescriptor getClassDescriptor( + String className, + ClassLoader classLoader) throws ClassNotFoundException { + ClassDescriptor result = descriptors.get(className); if (result != null) { return result; } -// if (result == null) { - if (JAXXEngine.isRegistred() && JAXXEngine.get().getSymbolTable(className) != null) { - result = createClassDescriptorFromSymbolTable(className, classLoader); - } else { - if (classLoader == null) { - classLoader = ClassDescriptorLoader.class.getClassLoader(); - } + JAXXEngine engine = JAXXFactory.isEngineRegistred() ? + JAXXFactory.getEngine() : null; - String relativePath = className.replaceAll("\\.", "/"); - String relativePathPattern = ".*";// + className + ".*"; // used to ensure that the located resource has the right character cases - // find the most recently updated source for the class -- Java source, JAXX source, or compiled class file - long javaLastModified = -1; - URL javaFile = classLoader.getResource(relativePath + ".java"); - if (javaFile != null && javaFile.toString().startsWith("file:") && javaFile.toString().matches(relativePathPattern)) { - javaLastModified = JAXXCompiler.URLtoFile(javaFile).lastModified(); - } + if (engine != null) { - long classLastModified = -1; - URL classFile = classLoader.getResource(relativePath + ".class"); - if (classFile != null && classFile.toString().startsWith("file:") && classFile.toString().matches(relativePathPattern)) { - classLastModified = JAXXCompiler.URLtoFile(classFile).lastModified(); - } + SymbolTable symbolTable = engine.getSymbolTable(className); - long jaxxLastModified = -1; - URL jaxxFile = classLoader.getResource(relativePath + ".jaxx"); - if (jaxxFile != null && jaxxFile.toString().startsWith("file:") && jaxxFile.toString().matches(relativePathPattern)) { - File jaxxFilePath = JAXXCompiler.URLtoFile(jaxxFile); - jaxxLastModified = jaxxFilePath.lastModified(); - String simplePath = jaxxFilePath.getPath(); - simplePath = simplePath.substring(0, simplePath.length() - ".jaxx".length()); - File cssFilePath = new File(simplePath + ".css"); - if (cssFilePath.exists()) { - jaxxLastModified = Math.max(jaxxLastModified, cssFilePath.lastModified()); - } - File scriptFilePath = new File(simplePath + ".script"); - if (scriptFilePath.exists()) { - jaxxLastModified = Math.max(jaxxLastModified, scriptFilePath.lastModified()); - } + if (symbolTable != null) { + + JAXXCompiler compiler = engine.getJAXXCompiler(className); + + result = createClassDescriptorFromSymbolTable( + compiler, + className, + classLoader + ); + descriptors.put(className, result); + return result; } + } - if (jaxxLastModified != -1 && JAXXEngine.isRegistred() && JAXXEngine.get().getSymbolTable(className) == null) { - jaxxLastModified = -1; // file has been modified, but wasn't included in this + // the class is not in this compile set, try to have it from java + // sources or classes. + + if (classLoader == null) { + classLoader = ClassDescriptorLoader.class.getClassLoader(); + } + + String relativePath = className.replaceAll("\\.", "/"); + String relativePathPattern = ".*";// + className + ".*"; // used to ensure that the located resource has the right character cases + + // find the most recently updated source for the class -- Java source, JAXX source, or compiled class file + long javaLastModified = -1; + URL javaFile = classLoader.getResource(relativePath + ".java"); + if (javaFile != null && + javaFile.toString().startsWith("file:") && + javaFile.toString().matches(relativePathPattern)) { + javaLastModified = JAXXCompiler.URLtoFile(javaFile).lastModified(); + } + + long classLastModified = -1; + URL classFile = classLoader.getResource(relativePath + ".class"); + if (classFile != null && + classFile.toString().startsWith("file:") && + classFile.toString().matches(relativePathPattern)) { + classLastModified = JAXXCompiler.URLtoFile(classFile).lastModified(); + } + + long jaxxLastModified = -1; + URL jaxxFile = classLoader.getResource(relativePath + ".jaxx"); + if (jaxxFile != null && + jaxxFile.toString().startsWith("file:") && + jaxxFile.toString().matches(relativePathPattern)) { + File jaxxFilePath = JAXXCompiler.URLtoFile(jaxxFile); + jaxxLastModified = jaxxFilePath.lastModified(); + String simplePath = jaxxFilePath.getPath(); + simplePath = simplePath.substring(0, simplePath.length() - ".jaxx".length()); + File cssFilePath = new File(simplePath + ".css"); + if (cssFilePath.exists()) { + jaxxLastModified = Math.max(jaxxLastModified, cssFilePath.lastModified()); } - // compilation set so we don't have a symbol table + File scriptFilePath = new File(simplePath + ".script"); + if (scriptFilePath.exists()) { + jaxxLastModified = Math.max(jaxxLastModified, scriptFilePath.lastModified()); + } + } - if (javaLastModified != -1 || classLastModified != -1 || jaxxLastModified != -1) { - if (jaxxLastModified > classLastModified && jaxxLastModified > javaLastModified) { - result = createClassDescriptorFromSymbolTable(className, classLoader); - } else if (javaLastModified > classLastModified && javaLastModified > jaxxLastModified) { - result = createClassDescriptorFromJavaSource(javaFile, classLoader); - } - } - // else work off of the class file. This also handles the case where the class is available, but wasn't in a location where - // we could check its last modified date (in a JAR, over the network, etc.) - if (result == null) { + if (classLastModified != -1) { + + // there is a class + + if (classLastModified >= javaLastModified && classLastModified >= jaxxLastModified) { + + // ok class is up to date, choose it Class<?> javaClass = getClass(className, classLoader); result = createClassDescriptorFromClass(javaClass); + descriptors.put(className, result); + return result; } + + // the class is not the last modified resource, do not use it } - descriptors.put(className, result); + + if (javaLastModified != -1) { + + // there is a java source + + if (javaLastModified > jaxxLastModified) { + + // ok java source is up to date, choose it + result = createClassDescriptorFromJavaSource(javaFile, classLoader); + + descriptors.put(className, result); // } - return result; + return result; + } + + // the java source is not the last modified resource, do not use it + + } + +// if (jaxxLastModified != -1) { +// +// // there is a jaxx file, use it +// +// compiler = engine.getJAXXCompiler(className); +// +// result = createClassDescriptorFromSymbolTable( +// compiler, +// className, +// classLoader +// ); +// // result = createClassDescriptorFromSymbolTable(className, classLoader); +// descriptors.put(className, result); +// return result; +// } + + // last fall back for class + Class<?> javaClass = getClass(className, classLoader); + result = createClassDescriptorFromClass(javaClass); + + if (result != null) { + descriptors.put(className, result); + return result; + } + + // can NOT come here, means could not find result... + + throw new IllegalStateException("Can not find descriptor for " + className); +// +// if (jaxxLastModified != -1 && JAXXFactory.isEngineRegistred() && symbolTable == null) { +// jaxxLastModified = -1; // file has been modified, but wasn't included in this +// } +// // compilation set so we don't have a symbol table +// +// if (javaLastModified != -1 || classLastModified != -1 || jaxxLastModified != -1) { +// +// if (javaLastModified > classLastModified && javaLastModified > jaxxLastModified) { +// result = createClassDescriptorFromJavaSource(javaFile, classLoader); +// } +//// if (jaxxLastModified > classLastModified && jaxxLastModified > javaLastModified) { +//// result = createClassDescriptorFromSymbolTable(className, classLoader); +//// } else if (javaLastModified > classLastModified && javaLastModified > jaxxLastModified) { +//// result = createClassDescriptorFromJavaSource(javaFile, classLoader); +//// } +// } +// // else work off of the class file. This also handles the case where +// // the class is available, but wasn't in a location where +// // we could check its last modified date (in a JAR, over the network, etc.) +// if (result == null) { +// Class<?> javaClass = getClass(className, classLoader); +// result = createClassDescriptorFromClass(javaClass); +// } +// descriptors.put(className, result); +//// } +// return result; } public static ClassDescriptor getClassDescriptor(Class<?> javaClass) { try { - return getClassDescriptor(javaClass.getName(), javaClass.getClassLoader()); + return getClassDescriptor( + javaClass.getName(), + javaClass.getClassLoader() + ); } catch (ClassNotFoundException e) { throw new RuntimeException(e); } } - public static Class<?> getPrimitiveBoxedClass(String className) throws ClassNotFoundException { + public static Class<?> getPrimitiveBoxedClass(String className) { if (className.equals("boolean")) { return Boolean.class; } @@ -174,7 +291,8 @@ return null; } - public static Class<?> getPrimitiveClass(String className) throws ClassNotFoundException { + public static Class<?> getPrimitiveClass( + String className) throws ClassNotFoundException { if (className.equals("boolean")) { return boolean.class; } @@ -276,7 +394,8 @@ } } - private static MethodDescriptor createMethodDescriptor(Method javaMethod, ClassLoader classLoader) { + private static MethodDescriptor createMethodDescriptor(Method javaMethod, + ClassLoader classLoader) { String methodName = javaMethod.getName(); int modifiers = javaMethod.getModifiers(); String returnType = javaMethod.getReturnType().getName(); @@ -288,7 +407,8 @@ return new MethodDescriptor(methodName, modifiers, returnType, parameters, classLoader); } - private static FieldDescriptor createFieldDescriptor(Field javaField, ClassLoader classLoader) { + private static FieldDescriptor createFieldDescriptor(Field javaField, + ClassLoader classLoader) { String fieldName = javaField.getName(); int modifiers = javaField.getModifiers(); String type = javaField.getType().getName(); @@ -296,7 +416,8 @@ } private static JAXXObjectDescriptor getJAXXObjectDescriptor(Class<?> jaxxClass) { - if (!JAXXObject.class.isAssignableFrom(jaxxClass) || jaxxClass == JAXXObject.class) { + if (!JAXXObject.class.isAssignableFrom(jaxxClass) || + JAXXObject.class.equals(jaxxClass)) { return null; } try { @@ -313,22 +434,32 @@ private static ClassDescriptor createClassDescriptorFromJavaSource(URL javaSource, ClassLoader classLoader) throws ClassNotFoundException { try { - if (log.isDebugEnabled()) { - log.debug("for source "+javaSource); - } InputStream in = javaSource.openStream(); + ClassDescriptor result = null; Reader reader = new InputStreamReader(in, "utf-8"); - ClassDescriptor result = JavaFileParser.parseJavaFile(javaSource.toString(), reader, classLoader); - reader.close(); + try { + if (log.isDebugEnabled()) { + log.debug("for source " + javaSource); + } + result = JavaFileParser.parseJavaFile(javaSource.toString(), reader, classLoader); + } finally { + + reader.close(); + } return result; } catch (IOException e) { throw new ClassNotFoundException(e.toString()); } } - private static ClassDescriptor createClassDescriptorFromSymbolTable(String className, ClassLoader classLoader) throws ClassNotFoundException { - final JAXXCompiler compiler = JAXXEngine.get().getJAXXCompiler(className); - final SymbolTable symbolTable = JAXXEngine.get().getSymbolTable(className); + private static ClassDescriptor createClassDescriptorFromSymbolTable( + final JAXXCompiler compiler, + String className, + ClassLoader classLoader) throws ClassNotFoundException { + + final SymbolTable symbolTable = compiler.getSymbolTable(); +// final JAXXCompiler compiler = JAXXFactory.getEngine().getJAXXCompiler(className); +// final SymbolTable symbolTable = JAXXFactory.getEngine().getSymbolTable(className); if (symbolTable == null) { throw new CompilerException("Internal error: no symbol table was generated for class '" + className + "'"); } @@ -383,9 +514,9 @@ } interfaces.add(JAXXObject.class.getName()); return new ClassDescriptor(className, packageName, symbolTable.getSuperclassName(), - interfaces.toArray(new String[interfaces.size()]), false, false, null, null, classLoader, - publicMethods.toArray(new MethodDescriptor[publicMethods.size()]), - publicFields.toArray(new FieldDescriptor[publicFields.size()])) { + interfaces.toArray(new String[interfaces.size()]), false, false, null, null, classLoader, + publicMethods.toArray(new MethodDescriptor[publicMethods.size()]), + publicFields.toArray(new FieldDescriptor[publicFields.size()])) { @Override public FieldDescriptor getDeclaredFieldDescriptor(String name) throws NoSuchFieldException { @@ -444,7 +575,7 @@ @Override public MethodDescriptor getDeclaredMethodDescriptor(String name, ClassDescriptor... parameterTypes) throws NoSuchMethodException { try { - Class[] parameterTypeClasses = new Class[parameterTypes.length]; + Class<?>[] parameterTypeClasses = new Class[parameterTypes.length]; for (int i = 0; i < parameterTypes.length; i++) { parameterTypeClasses[i] = Class.forName(parameterTypes[i].getName()); } Modified: trunk/jaxx-compiler/src/main/java/jaxx/compiler/reflect/JavaFileParser.java =================================================================== --- trunk/jaxx-compiler/src/main/java/jaxx/compiler/reflect/JavaFileParser.java 2010-05-02 11:04:42 UTC (rev 1864) +++ trunk/jaxx-compiler/src/main/java/jaxx/compiler/reflect/JavaFileParser.java 2010-05-02 16:55:27 UTC (rev 1865) @@ -27,7 +27,7 @@ import jaxx.compiler.CompilerException; import jaxx.compiler.JAXXCompiler; -import jaxx.compiler.JAXXEngine; +import jaxx.compiler.JAXXFactory; import jaxx.compiler.java.parser.JavaParser; import jaxx.compiler.java.parser.JavaParserTreeConstants; import jaxx.compiler.java.parser.ParseException; @@ -50,13 +50,15 @@ static private final Log log = LogFactory.getLog(JavaFileParser.class); private JAXXCompiler compiler; private String className; - private String packageName = null; + private String packageName; private String superclass = "java.lang.Object"; private List<MethodDescriptor> methods = new ArrayList<MethodDescriptor>(); private List<FieldDescriptor> fields = new ArrayList<FieldDescriptor>(); + public static final String[] EMPTY_STRING_ARRAY = new String[0]; + private JavaFileParser(ClassLoader classLoader) { - compiler = JAXXEngine.createDummyCompiler(classLoader); + compiler = JAXXFactory.newDummyCompiler(classLoader); } public static ClassDescriptor parseJavaFile(String displayName, Reader src, ClassLoader classLoader) throws ClassNotFoundException { @@ -102,7 +104,7 @@ //for (ClassDescriptor superclassInterface : superclassInterfaces) { //interfaces.add(superclassInterface.getName()); //} - return new ClassDescriptor(parser.className, parser.packageName, parser.superclass, new String[0], false, false, null, null, classLoader, + return new ClassDescriptor(parser.className, parser.packageName, parser.superclass, EMPTY_STRING_ARRAY, false, false, null, null, classLoader, publicMethods.toArray(new MethodDescriptor[publicMethods.size()]), publicFields.toArray(new FieldDescriptor[publicFields.size()])) { Modified: trunk/jaxx-compiler/src/main/java/jaxx/compiler/script/ScriptManager.java =================================================================== --- trunk/jaxx-compiler/src/main/java/jaxx/compiler/script/ScriptManager.java 2010-05-02 11:04:42 UTC (rev 1864) +++ trunk/jaxx-compiler/src/main/java/jaxx/compiler/script/ScriptManager.java 2010-05-02 16:55:27 UTC (rev 1865) @@ -108,7 +108,7 @@ private void preprocessScriptNode(SimpleNode node, boolean staticContext) throws CompilerException { // identify static methods and initializers -- we can't fire events statically if (node.getId() == JavaParserTreeConstants.JJTMETHODDECLARATION) { - if (node.getParent().getChild(0).getText().indexOf("static") != -1) { + if (node.getParent().getChild(0).getText().contains("static")) { staticContext = true; } } else if (node.getId() == JavaParserTreeConstants.JJTINITIALIZER) { @@ -128,7 +128,8 @@ } if (!staticContext) { String lhs = null; - if (id == JavaParserTreeConstants.JJTASSIGNMENTEXPRESSION || (id == JavaParserTreeConstants.JJTPOSTFIXEXPRESSION && node.jjtGetNumChildren() == 2)) { + if (id == JavaParserTreeConstants.JJTASSIGNMENTEXPRESSION || + id == JavaParserTreeConstants.JJTPOSTFIXEXPRESSION && node.jjtGetNumChildren() == 2) { lhs = ((SimpleNode) node.jjtGetChild(0)).getText().trim(); } else if (id == JavaParserTreeConstants.JJTPREINCREMENTEXPRESSION || id == JavaParserTreeConstants.JJTPREDECREMENTEXPRESSION) { lhs = ((SimpleNode) node.jjtGetChild(0)).getText().trim(); @@ -295,7 +296,8 @@ } String className = declarationTokens[declarationTokens.length - 2]; String type = TagManager.resolveClassName(className, compiler); - compiler.addScriptField(new FieldDescriptor(name, Modifier.PUBLIC, type, compiler.getClassLoader())); // TODO: determine the actual modifiers + compiler.addScriptField(new FieldDescriptor(name, Modifier.PUBLIC, type, compiler.getClassLoader())); + // TODO: determine the actual modifiers if (equals != -1 && !isFinal && !isStatic) { // declare the field in the class body, but wait to actually initialize it compiler.appendBodyCode(text.substring(0, equals).trim() + ";"); String initializer = text.substring(equals + 1).trim(); Modified: trunk/jaxx-compiler/src/main/java/jaxx/compiler/spi/DefaultInitializer.java =================================================================== --- trunk/jaxx-compiler/src/main/java/jaxx/compiler/spi/DefaultInitializer.java 2010-05-02 11:04:42 UTC (rev 1864) +++ trunk/jaxx-compiler/src/main/java/jaxx/compiler/spi/DefaultInitializer.java 2010-05-02 16:55:27 UTC (rev 1865) @@ -112,7 +112,8 @@ /** * Initializes support provided from JAXX (java, swing and validation). - * + * + * @plexus.component role-hint="default" role="jaxx.compiler.spi.Initializer" */ public class DefaultInitializer implements Initializer { Modified: trunk/jaxx-compiler/src/main/java/jaxx/compiler/tags/TagManager.java =================================================================== --- trunk/jaxx-compiler/src/main/java/jaxx/compiler/tags/TagManager.java 2010-05-02 11:04:42 UTC (rev 1864) +++ trunk/jaxx-compiler/src/main/java/jaxx/compiler/tags/TagManager.java 2010-05-02 16:55:27 UTC (rev 1865) @@ -28,13 +28,11 @@ import jaxx.compiler.ClassMap; import jaxx.compiler.CompilerException; import jaxx.compiler.JAXXCompiler; -import jaxx.compiler.JAXXEngine; import jaxx.compiler.reflect.ClassDescriptor; import jaxx.compiler.reflect.ClassDescriptorLoader; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import java.io.IOException; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.net.URL; @@ -115,11 +113,10 @@ private TagManager() { /* not instantiable */ } - public static void reset(boolean verbose) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException { + public static void reset() { registeredBeans.clear(); registeredTags.clear(); defaultNamespaces.clear(); - JAXXEngine.loadLibraries(verbose); } /** @@ -132,7 +129,8 @@ * @param handler the <code>TagHandler</code> class, which must descend from <code>DefaultObjectHandler</code> * @throws IllegalArgumentException if the handler class does not descend from <code>DefaultObjectHandler</code> */ - public static <T extends TagHandler> void registerBean(ClassDescriptor beanClass, Class<T> handler) { + public static <T extends TagHandler> void registerBean(ClassDescriptor beanClass, + Class<T> handler) { if (!DefaultObjectHandler.class.isAssignableFrom(handler)) { throw new IllegalArgumentException("handler class must be a subclass of DefaultObjectHandler"); } @@ -225,6 +223,50 @@ } /** + * @param klass the java class + * @return the <code>TagHandler</code> that should be used to process the specified class. + * Only <code>TagHandlers</code> previously registered with <code>registerBean</code> + * are considered. + * @throws CompilerException ? + */ + public static DefaultObjectHandler getTagHandler(Class<?> klass) throws CompilerException { + + ClassDescriptor beanClass = ClassDescriptorLoader.getClassDescriptor(klass); + DefaultObjectHandler tagHandler = getTagHandler(beanClass); + return tagHandler; +// +// try { +// if (beanClass == null) { +// throw new NullPointerException("beanClass parameter can not be null"); +// } +// if (beanClass.getName() == null) { +// throw new NullPointerException("beanClass can not be null : "+beanClass); +// } +// +// String namespace = getNamespace(beanClass); +// String tag = getSimpleName(beanClass); +// DefaultObjectHandler handler = (DefaultObjectHandler) registeredTags.get(new QName(namespace, tag)); +// if (handler == null) { +// Class<? extends TagHandler> handlerClass = registeredBeans.get(beanClass); +// if (handlerClass == null) { +// throw new CompilerException("unable to find handler for " + beanClass); +// } +// Constructor<? extends TagHandler> constructor = handlerClass.getConstructor(ClassDescriptor.class); +// handler = (DefaultObjectHandler) constructor.newInstance(beanClass); +// registerTag(namespace, tag, handler); +// } +// return handler; +// } catch (InstantiationException e) { +// throw new RuntimeException(e); +// } catch (NoSuchMethodException e) { +// throw new RuntimeException(e); +// } catch (IllegalAccessException e) { +// throw new RuntimeException(e); +// } catch (InvocationTargetException e) { +// throw new RuntimeException(e); +// } + } + /** * @param beanClass the tag class * @return the <code>TagHandler</code> that should be used to process the specified class. * Only <code>TagHandlers</code> previously registered with <code>registerBean</code> @@ -387,7 +429,8 @@ ClassDescriptor beanClass = ClassDescriptorLoader.getClassDescriptor(className, compiler.getClassLoader()); handler = getTagHandler(beanClass); } catch (ClassNotFoundException e) { - e.printStackTrace(); + log.error(e); +// e.printStackTrace(); } } } @@ -411,7 +454,7 @@ if (name.endsWith("[]")) { return resolveClassName(name.substring(0, name.length() - 2), compiler) + "[]"; } - if (name.indexOf("<") != -1) { + if (name.contains("<")) { name = name.substring(0, name.indexOf("<")); // strip off generic types } Modified: trunk/jaxx-compiler/src/main/java/jaxx/compiler/tags/validator/BeanValidatorHandler.java =================================================================== --- trunk/jaxx-compiler/src/main/java/jaxx/compiler/tags/validator/BeanValidatorHandler.java 2010-05-02 11:04:42 UTC (rev 1864) +++ trunk/jaxx-compiler/src/main/java/jaxx/compiler/tags/validator/BeanValidatorHandler.java 2010-05-02 16:55:27 UTC (rev 1865) @@ -25,8 +25,8 @@ package jaxx.compiler.tags.validator; +import jaxx.compiler.CompiledObject; import jaxx.compiler.CompilerException; -import jaxx.compiler.CompiledObject; import jaxx.compiler.JAXXCompiler; import jaxx.compiler.beans.JAXXBeanInfo; import jaxx.compiler.beans.JAXXPropertyDescriptor; @@ -35,14 +35,13 @@ import jaxx.compiler.reflect.ClassDescriptorLoader; import jaxx.compiler.tags.DefaultObjectHandler; import jaxx.compiler.types.TypeManager; +import jaxx.runtime.validator.swing.SwingValidator; import jaxx.runtime.validator.swing.SwingValidatorUtil; -import jaxx.runtime.validator.swing.SwingValidator; import jaxx.runtime.validator.swing.ui.AbstractBeanValidatorUI; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.w3c.dom.Element; -import java.beans.IntrospectionException; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; @@ -54,56 +53,86 @@ public class BeanValidatorHandler extends DefaultObjectHandler { public static final String TAG = "BeanValidator"; + public static final String BEAN_ATTRIBUTE = "bean"; + public static final String BEAN_CLASS_ATTRIBUTE = "beanClass"; + public static final String BEAN_INITIALIZER_ATTRIBUTE = "beanInitializer"; + public static final String ERROR_LIST_MODEL_ATTRIBUTE = "errorListModel"; + public static final String ERROR_TABLE_MODEL_ATTRIBUTE = "errorTableModel"; + public static final String ERROR_LIST_ATTRIBUTE = "errorList"; + public static final String ERROR_TABLE_ATTRIBUTE = "errorTable"; //TODO-TC20091024 should change this default value to errorListModel + public static final String ERROR_LIST_MODEL_DEFAULT = "errors"; //TODO-TC20091024 should change this default value to errorTableModel + public static final String ERROR_TABLE_MODEL_DEFAULT = "errors2"; + public static final String ERROR_LIST_DEFAULT = "errorList"; + public static final String ERROR_TABLE_DEFAULT = "errorTable"; + public static final String AUTOFIELD_ATTRIBUTE = "autoField"; + public static final String UI_CLASS_ATTRIBUTE = "uiClass"; + public static final String STRICT_MODE_ATTRIBUTE = "strictMode"; + public static final String CONTEXT_NAME_ATTRIBUTE = "contextName"; //public static final String SCOPE_ATTRIBUTE = "scope"; + public static final String PARENT_VALIDATOR_ATTRIBUTE = "parentValidator"; - /** - * to use log facility, just put in your code: log.info(\"...\"); - */ + + /** to use log facility, just put in your code: log.info(\"...\"); */ static Log log = LogFactory.getLog(BeanValidatorHandler.class); - protected static Map<JAXXCompiler, List<CompiledBeanValidator>> validators = new HashMap<JAXXCompiler, List<CompiledBeanValidator>>(); - protected static Map<JAXXCompiler, List<String>> validatedComponents = new HashMap<JAXXCompiler, List<String>>(); + protected static Map<JAXXCompiler, List<CompiledBeanValidator>> validators = + new HashMap<JAXXCompiler, List<CompiledBeanValidator>>(); + + protected static Map<JAXXCompiler, List<String>> validatedComponents = + new HashMap<JAXXCompiler, List<String>>(); + public BeanValidatorHandler(ClassDescriptor beanClass) { super(beanClass); - ClassDescriptorLoader.checkSupportClass(getClass(), beanClass, SwingValidator.class); + ClassDescriptorLoader.checkSupportClass( + getClass(), + beanClass, + SwingValidator.class + ); } @Override - protected CompiledObject createCompiledObject(String id, JAXXCompiler compiler) { + protected CompiledObject createCompiledObject(String id, + JAXXCompiler compiler) { return new CompiledBeanValidator(id, getBeanClass(), compiler); } @Override - protected void compileChildTagFirstPass(Element tag, JAXXCompiler compiler) throws CompilerException, IOException { + protected void compileChildTagFirstPass( + Element tag, + JAXXCompiler compiler) throws CompilerException, IOException { if (log.isDebugEnabled()) { log.debug(tag); } if (!tag.getLocalName().equals(FieldValidatorHandler.TAG)) { - compiler.reportError("tag '" + tag.getParentNode().getLocalName() + "' may only contain " + FieldValidatorHandler.TAG + " as children, but found : " + tag.getLocalName()); + compiler.reportError( + "tag '" + tag.getParentNode().getLocalName() + + "' may only contain " + FieldValidatorHandler.TAG + + " as children, but found : " + tag.getLocalName()); } else { compiler.compileFirstPass(tag); } } @Override - public void compileSecondPass(Element tag, JAXXCompiler compiler) throws CompilerException, IOException { + public void compileSecondPass( + Element tag, JAXXCompiler compiler) throws CompilerException, IOException { super.compileSecondPass(tag, compiler); @@ -144,7 +173,8 @@ } if (error) { - log.warn("error were detected in second compile pass of CompiledObject [" + info + "]"); + log.warn("error were detected in second compile pass " + + "of CompiledObject [" + info + "]"); } // close the compiled object @@ -152,43 +182,66 @@ } @Override - protected void setDefaults(CompiledObject object, Element tag, JAXXCompiler compiler) { + protected void setDefaults(CompiledObject object, + Element tag, + JAXXCompiler compiler) { // open the compiled object compiler.openInvisibleComponent(object); } @Override - public void setAttribute(CompiledObject object, String propertyName, String stringValue, boolean inline, JAXXCompiler compiler) { + public void setAttribute(CompiledObject object, + String propertyName, + String stringValue, + boolean inline, + JAXXCompiler compiler) { if (log.isDebugEnabled()) { log.debug(propertyName + " : " + stringValue + " for " + object); } - // delegate to the compiled object with is statefull (but not the tag handler) + // delegate to the compiled object with is statefull + // (but not the tag handler) object.addProperty(propertyName, stringValue); } /** - * The compiled objet representing a BeanValidator to be generated in JAXXObject + * The compiled objet representing a BeanValidator to be generated in + * JAXXObject * * @author tchemit <chemit@codelutin.com> */ public static class CompiledBeanValidator extends CompiledObject { protected Map<String, String> fields; + protected Map<String, String> excludeFields; + protected String bean; + protected String beanClass; + protected String contextName; + protected String uiClass; + protected String errorListModel; + protected String errorList; + protected Boolean autoField; + protected Boolean strictMode; + protected JAXXBeanInfo beanDescriptor; + protected String errorTableModel; + protected String errorTable; + protected String parentValidator; - public CompiledBeanValidator(String id, ClassDescriptor objectClass, JAXXCompiler compiler) { + public CompiledBeanValidator(String id, + ClassDescriptor objectClass, + JAXXCompiler compiler) { //TC-20090524 Use the real class descriptor, not the one by default, //TC-20090524 otherwise can not override the validator class while generation //super(id, objectClass, compiler); @@ -196,14 +249,16 @@ fields = new TreeMap<String, String>(); excludeFields = new TreeMap<String, String>(); if (log.isDebugEnabled()) { - log.debug("validator objectClass " + super.getObjectClass()); + log.debug("validator objectClass " + getObjectClass()); } } - protected static ClassDescriptor getDescriptor(ClassDescriptor objectClass, JAXXCompiler compiler) { - ClassDescriptor result = objectClass; - Class<?> validatorClass = compiler.getConfiguration().getValidatorClass(); - result = ClassDescriptorLoader.getClassDescriptor(validatorClass); + protected static ClassDescriptor getDescriptor( + ClassDescriptor objectClass, JAXXCompiler compiler) { + Class<?> validatorClass = + compiler.getConfiguration().getValidatorClass(); + ClassDescriptor result = + ClassDescriptorLoader.getClassDescriptor(validatorClass); return result; } @@ -284,14 +339,20 @@ if (AUTOFIELD_ATTRIBUTE.equals(property)) { if (value != null && !value.trim().isEmpty()) { - autoField = (Boolean) TypeManager.convertFromString(value.trim(), Boolean.class); + autoField = (Boolean) TypeManager.convertFromString( + value.trim(), + Boolean.class + ); } return; } if (STRICT_MODE_ATTRIBUTE.equals(property)) { if (value != null && !value.trim().isEmpty()) { - strictMode = (Boolean) TypeManager.convertFromString(value.trim(), Boolean.class); + strictMode = (Boolean) TypeManager.convertFromString( + value.trim(), + Boolean.class + ); } return; } @@ -303,7 +364,8 @@ return; } - throw new CompilerException("property " + property + " is not allowed on object " + this); + throw new CompilerException("property " + property + + " is not allowed on object " + this); } public String getBean() { @@ -354,40 +416,57 @@ return null; } }*/ - ClassDescriptor beanClassDescriptor = ClassDescriptorLoader.getClassDescriptor(beanClass); - beanDescriptor = DefaultObjectHandler.getJAXXBeanInfo(beanClassDescriptor); - } catch (ClassNotFoundException e) { - compiler.reportError("could not load class " + beanClassName); - } catch (IntrospectionException e) { - compiler.reportError("could not load class " + beanClassName); + ClassDescriptor beanClassDescriptor = + ClassDescriptorLoader.getClassDescriptor(beanClass); + beanDescriptor = DefaultObjectHandler.getJAXXBeanInfo( + beanClassDescriptor); + + } catch (Exception e) { + compiler.reportError( + "could not load class " + beanClassName); } } return beanDescriptor; } @Override - public void addChild(CompiledObject child, String constraints, JAXXCompiler compiler) throws CompilerException { + public void addChild(CompiledObject child, + String constraints, + JAXXCompiler compiler) throws CompilerException { // do nothing - compiler.reportError("can not add CompiledObject in the tag '" + TAG + " (only field tags)"); + compiler.reportError("can not add CompiledObject in the tag '" + + TAG + " (only field tags)"); } public boolean foundBean() { return !(beanClass == null || beanClass.isEmpty()); } - protected boolean addUiClass(BeanValidatorHandler handler, JAXXCompiler compiler) { + protected boolean addUiClass(BeanValidatorHandler handler, + JAXXCompiler compiler) { boolean withError = false; - if (uiClass == null && compiler.getConfiguration().getDefaultErrorUI() != null) { + if (uiClass == null && + compiler.getConfiguration().getDefaultErrorUI() != null) { uiClass = compiler.getConfiguration().getDefaultErrorUI().getName(); } if (uiClass != null) { try { - ClassDescriptor uiClazz = ClassDescriptorLoader.getClassDescriptor(uiClass); + ClassDescriptor uiClazz = + ClassDescriptorLoader.getClassDescriptor(uiClass); if (!ClassDescriptorLoader.getClassDescriptor(AbstractBeanValidatorUI.class).isAssignableFrom(uiClazz)) { - compiler.reportError("attribute 'ui' :'" + uiClass + "' is not assignable from class " + AbstractBeanValidatorUI.class); + compiler.reportError( + "attribute 'ui' :'" + uiClass + + "' is not assignable from class " + + AbstractBeanValidatorUI.class + ); withError = true; } else { - String code = handler.getSetPropertyCode(getJavaCode(), UI_CLASS_ATTRIBUTE, uiClazz.getName() + ".class", compiler); + String code = handler.getSetPropertyCode( + getJavaCode(), + UI_CLASS_ATTRIBUTE, + uiClazz.getName() + ".class", + compiler + ); appendAdditionCode(code); } } catch (ClassNotFoundException e) { @@ -399,70 +478,120 @@ return withError; } - protected boolean addErrorListModel(Element tag, BeanValidatorHandler handler, JAXXCompiler compiler) { + protected boolean addErrorListModel(Element tag, + BeanValidatorHandler handler, + JAXXCompiler compiler) { if (errorListModel == null) { // try with the default "errors" - if (!compiler.checkReference(tag, ERROR_LIST_MODEL_DEFAULT, false, ERROR_LIST_MODEL_ATTRIBUTE)) { + if (!compiler.checkReference( + tag, + ERROR_LIST_MODEL_DEFAULT, + false, + ERROR_LIST_MODEL_ATTRIBUTE)) { return false; } errorListModel = ERROR_LIST_MODEL_DEFAULT; } else { - if (errorListModel.startsWith("{") && errorListModel.endsWith("}")) { + if (errorListModel.startsWith("{") && + errorListModel.endsWith("}")) { // this is a script, no check here - errorListModel = errorListModel.substring(1, errorListModel.length() - 1).trim(); - } else if (!compiler.checkReference(tag, errorListModel, true, ERROR_LIST_MODEL_ATTRIBUTE)) { + errorListModel = errorListModel.substring( + 1, + errorListModel.length() - 1).trim(); + } else if (!compiler.checkReference( + tag, + errorListModel, + true, + ERROR_LIST_MODEL_ATTRIBUTE)) { // errorListModel is not defined return true; } } - String code = handler.getSetPropertyCode(getJavaCode(), ERROR_LIST_MODEL_ATTRIBUTE, errorListModel, compiler); + String code = handler.getSetPropertyCode( + getJavaCode(), + ERROR_LIST_MODEL_ATTRIBUTE, + errorListModel, + compiler + ); appendAdditionCode(code); return false; } - protected boolean addErrorTableModel(Element tag, BeanValidatorHandler handler, JAXXCompiler compiler) { + protected boolean addErrorTableModel(Element tag, + BeanValidatorHandler handler, + JAXXCompiler compiler) { if (errorTableModel == null) { // try with the default "errors" - if (!compiler.checkReference(tag, ERROR_TABLE_MODEL_DEFAULT, false, ERROR_LIST_MODEL_ATTRIBUTE)) { + if (!compiler.checkReference( + tag, + ERROR_TABLE_MODEL_DEFAULT, + false, + ERROR_LIST_MODEL_ATTRIBUTE)) { return false; } errorTableModel = ERROR_TABLE_MODEL_DEFAULT; } else { - if (errorTableModel.startsWith("{") && errorTableModel.endsWith("}")) { + if (errorTableModel.startsWith("{") && + errorTableModel.endsWith("}")) { // this is a script, no check here - errorTableModel = errorTableModel.substring(1, errorTableModel.length() - 1).trim(); - } else if (!compiler.checkReference(tag, errorTableModel, true, ERROR_TABLE_MODEL_ATTRIBUTE)) { + errorTableModel = errorTableModel.substring( + 1, errorTableModel.length() - 1).trim(); + } else if (!compiler.checkReference( + tag, + errorTableModel, + true, + ERROR_TABLE_MODEL_ATTRIBUTE)) { // errorListModel is not defined return true; } } - String code = handler.getSetPropertyCode(getJavaCode(), ERROR_TABLE_MODEL_ATTRIBUTE, errorTableModel, compiler); + String code = handler.getSetPropertyCode( + getJavaCode(), + ERROR_TABLE_MODEL_ATTRIBUTE, + errorTableModel, + compiler + ); appendAdditionCode(code); return false; } - protected boolean addParentValidator(Element tag, BeanValidatorHandler handler, JAXXCompiler compiler) { + protected boolean addParentValidator(Element tag, + BeanValidatorHandler handler, + JAXXCompiler compiler) { if (parentValidator != null) { String initializer; - if (parentValidator.startsWith("{") && parentValidator.endsWith("}")) { + if (parentValidator.startsWith("{") && + parentValidator.endsWith("}")) { // todo : should be able to bind - initializer = parentValidator.substring(1, parentValidator.length() - 1); + initializer = parentValidator.substring( + 1, + parentValidator.length() - 1 + ); } else { // the attribute referes an existing widget - if (!compiler.checkReference(tag, parentValidator, true, PARENT_VALIDATOR_ATTRIBUTE)) { + if (!compiler.checkReference( + tag, + parentValidator, + true, + PARENT_VALIDATOR_ATTRIBUTE)) { // parentValidator is not defined return true; } initializer = parentValidator; } - String code = handler.getSetPropertyCode(getJavaCode(), PARENT_VALIDATOR_ATTRIBUTE, initializer, compiler); + String code = handler.getSetPropertyCode( + getJavaCode(), + PARENT_VALIDATOR_ATTRIBUTE, + initializer, + compiler + ); appendAdditionCode(code); } return false; @@ -472,17 +601,26 @@ if (errorList == null) { // try with the default "errorList" - if (!compiler.checkReference(tag, ERROR_LIST_DEFAULT, false, ERROR_LIST_ATTRIBUTE)) { + if (!compiler.checkReference( + tag, + ERROR_LIST_DEFAULT, + false, + ERROR_LIST_ATTRIBUTE)) { return false; } errorList = ERROR_LIST_DEFAULT; } else { - if (!compiler.checkReference(tag, errorList, true, ERROR_LIST_ATTRIBUTE)) { + if (!compiler.checkReference( + tag, + errorList, + true, + ERROR_LIST_ATTRIBUTE)) { return true; } } - String code = SwingValidatorUtil.class.getName() + ".registerErrorListMouseListener(" + errorList + ");"; + String code = SwingValidatorUtil.class.getName() + + ".registerErrorListMouseListener(" + errorList + ");"; appendAdditionCode(code); return false; @@ -492,42 +630,60 @@ if (errorTable == null) { // try with the default "errorList" - if (!compiler.checkReference(tag, ERROR_TABLE_DEFAULT, false, ERROR_TABLE_ATTRIBUTE)) { + if (!compiler.checkReference(tag, + ERROR_TABLE_DEFAULT, + false, + ERROR_TABLE_ATTRIBUTE)) { return false; } errorTable = ERROR_TABLE_DEFAULT; } else { - if (!compiler.checkReference(tag, errorTable, true, ERROR_TABLE_ATTRIBUTE)) { + if (!compiler.checkReference(tag, + errorTable, + true, + ERROR_TABLE_ATTRIBUTE)) { return true; } } - String code = SwingValidatorUtil.class.getName() + ".registerErrorTableMouseListener(" + errorTable + ");"; + String code = SwingValidatorUtil.class.getName() + + ".registerErrorTableMouseListener(" + errorTable + + ");"; appendAdditionCode(code); return false; } - protected boolean addBean(Element tag, BeanValidatorHandler handler, JAXXCompiler compiler) { + protected boolean addBean(Element tag, + BeanValidatorHandler handler, + JAXXCompiler compiler) { if (beanClass == null || beanClass.isEmpty()) { // try to guest beanClass from bean attribute if (bean != null && !bean.isEmpty()) { beanClass = compiler.getSymbolTable().getClassTagIds().get(bean); if (beanClass == null) { - compiler.reportError("could not find class of the bean '" + bean + "', and no beanClass was setted"); + compiler.reportError( + "could not find class of the bean '" + bean + + "', and no beanClass was setted"); return true; } } } if (beanClass == null) { - compiler.reportError("tag '" + tag + "' requires a 'beanClass' attribute, and could not guest it from 'bean' attribute (no bean attribute setted...)"); + compiler.reportError( + "tag '" + tag + "' requires a 'beanClass' attribute, " + + "and could not guest it from 'bean' attribute " + + "(no bean attribute setted...)"); return true; } JAXXBeanInfo beanInfo = getBeanDescriptor(compiler); if (beanInfo == null) { - compiler.reportError(tag, "could not find descriptor of class " + beanClass); + compiler.reportError( + tag, + "could not find descriptor of class " + beanClass + ); return true; } @@ -536,9 +692,14 @@ if (bean.startsWith("{") && bean.endsWith("}")) { - String labelBinding = DataBindingHelper.processDataBindings(bean); + String labelBinding = + DataBindingHelper.processDataBindings(bean); if (labelBinding != null) { - compiler.getBindingHelper().registerDataBinding(getId() + ".bean", labelBinding, getId() + ".setBean(" + labelBinding + ");"); + compiler.getBindingHelper().registerDataBinding( + getId() + ".bean", + labelBinding, + getId() + ".setBean(" + labelBinding + ");" + ); } // // just has an intializer // beanInitializer = bean.substring(1, bean.length() - 1); @@ -546,13 +707,20 @@ bean = null; } else { - if (!compiler.checkReference(tag, bean, true, BEAN_ATTRIBUTE)) { + if (!compiler.checkReference(tag, + bean, + true, + BEAN_ATTRIBUTE)) { // could not find bean in compiled object return true; } if (isBeanUsedByValidator(compiler, bean)) { - compiler.reportError("the bean '" + bean + "' is already used in another the validator, can not used it in '" + tag + "'"); + compiler.reportError( + "the bean '" + bean + "' is already used in " + + "another the validator, can not used it in '" + + tag + "'" + ); return true; } @@ -564,13 +732,19 @@ } if (beanInitializer != null) { - String code = handler.getSetPropertyCode(getJavaCode(), BEAN_ATTRIBUTE, compiler.checkJavaCode(beanInitializer), compiler); + String code = handler.getSetPropertyCode( + getJavaCode(), + BEAN_ATTRIBUTE, + compiler.checkJavaCode(beanInitializer), + compiler + ); appendAdditionCode(code); } String beanClassName = beanInfo.getJAXXBeanDescriptor().getClassDescriptor().getName(); // contextName must be in constructor to able to init validator with his correct contextName - setConstructorParams(beanClassName + ".class, " + TypeManager.getJavaCode(contextName)); + setConstructorParams(beanClassName + ".class, " + + TypeManager.getJavaCode(contextName)); // add generic type to validator setGenericTypes(new String[]{beanClassName}); @@ -591,7 +765,9 @@ return false; } - private void registerValidator(JAXXCompiler compiler, CompiledBeanValidator compiledBeanValidator) { + private void registerValidator( + JAXXCompiler compiler, + CompiledBeanValidator compiledBeanValidator) { List<CompiledBeanValidator> vals = validators.get(compiler); if (vals == null) { vals = new ArrayList<CompiledBeanValidator>(); @@ -606,7 +782,8 @@ ids.addAll(compiledBeanValidator.getFields().values()); } - protected void addFieldRepresentations(Element tag, JAXXCompiler compiler) { + protected void addFieldRepresentations(Element tag, + JAXXCompiler compiler) { for (Entry<String, String> entry : fields.entrySet()) { String propertyName = entry.getKey(); String component = entry.getValue(); @@ -619,15 +796,21 @@ continue; } String keyCode = TypeManager.getJavaCode(propertyName); - appendAdditionCode(getJavaCode() + ".setFieldRepresentation(" + keyCode + ", " + component + ");"); + appendAdditionCode(getJavaCode() + ".setFieldRepresentation(" + + keyCode + ", " + component + ");"); } } - protected void registerAutoFieldBean(Element tag, JAXXCompiler compiler, JAXXBeanInfo beanInfo) { - for (JAXXPropertyDescriptor beanProperty : beanInfo.getJAXXPropertyDescriptors()) { + protected void registerAutoFieldBean(Element tag, + JAXXCompiler compiler, + JAXXBeanInfo beanInfo) { + for (JAXXPropertyDescriptor beanProperty : + beanInfo.getJAXXPropertyDescriptors()) { String descriptionName = beanProperty.getName(); if (log.isDebugEnabled()) { - log.debug("try to bind on bean " + beanInfo.getJAXXBeanDescriptor().getName() + " property " + descriptionName); + log.debug("try to bind on bean " + + beanInfo.getJAXXBeanDescriptor().getName() + + " property " + descriptionName); } if (beanProperty.getWriteMethodDescriptor() == null) { // read-only property @@ -641,7 +824,10 @@ // exclude field continue; } - if (!compiler.checkReference(tag, descriptionName, getStrictMode(), null)) { + if (!compiler.checkReference(tag, + descriptionName, + getStrictMode(), + null)) { // no editor component found continue; } @@ -652,15 +838,21 @@ for (Entry<String, String> entry : excludeFields.entrySet()) { String key = entry.getKey(); if (fields.containsKey(key)) { - compiler.reportWarning("field '" + key + "' can not be used and excluded at same time ! (field is skipped) for validator " + this); + compiler.reportWarning( + "field '" + key + "' can not be used and " + + "excluded at same time ! (field is skipped) " + + "for validator " + this + ); fields.remove(key); } } } - public void registerField(String id, String component, JAXXCompiler compiler) { + public void registerField(String id, String component, + JAXXCompiler compiler) { if (fields.containsKey(id)) { - compiler.reportError("duplicate field '" + id + "' for validator " + this); + compiler.reportError( + "duplicate field '" + id + "' for validator " + this); } else { if (log.isDebugEnabled()) { log.debug("add field <" + id + ":" + component + ">"); @@ -669,9 +861,12 @@ } } - public void registerExcludeField(String id, String component, JAXXCompiler compiler) { + public void registerExcludeField(String id, + String component, + JAXXCompiler compiler) { if (excludeFields.containsKey(id)) { - compiler.reportError("duplicate field '" + id + "' for validator " + this); + compiler.reportError( + "duplicate field '" + id + "' for validator " + this); } else { if (log.isDebugEnabled()) { log.debug("add excludeField <" + id + ":" + component + ">"); @@ -680,19 +875,25 @@ } } - protected boolean checkBeanProperty(JAXXCompiler compiler, String propertyName) { + protected boolean checkBeanProperty(JAXXCompiler compiler, + String propertyName) { - for (JAXXPropertyDescriptor beanProperty : getBeanDescriptor(compiler).getJAXXPropertyDescriptors()) { + for (JAXXPropertyDescriptor beanProperty : + getBeanDescriptor(compiler).getJAXXPropertyDescriptors()) { if (beanProperty.getName().equals(propertyName)) { if (beanProperty.getWriteMethodDescriptor() == null) { // read-onlyproperty - compiler.reportError("could not bind the readonly property '" + propertyName + "' on bean [" + getBean() + "] "); + compiler.reportError( + "could not bind the readonly property '" + + propertyName + "' on bean [" + getBean() + "] "); return false; } return true; } } - compiler.reportError("could not find the property '" + propertyName + "' on bean [" + getBean() + "] "); + compiler.reportError( + "could not find the property '" + propertyName + + "' on bean [" + getBean() + "] "); return false; } } @@ -702,9 +903,11 @@ * * @param compiler current compiler to use * @param beanId the bean to test - * @return <code>true</code> if the given bean is attached to a validator, <code>false</code> otherwise + * @return <code>true</code> if the given bean is attached to a validator, + * <code>false</code> otherwise */ - public static boolean isBeanUsedByValidator(JAXXCompiler compiler, String beanId) { + public static boolean isBeanUsedByValidator(JAXXCompiler compiler, + String beanId) { List<CompiledBeanValidator> beanValidatorList = validators.get(compiler); if (beanValidatorList != null) { for (CompiledBeanValidator validator : beanValidatorList) { @@ -718,10 +921,12 @@ /** * @param compiler compiler to use - * @return <code>true</code> if some validators were detected, <code>false</code> otherwise + * @return <code>true</code> if some validators were detected, + * <code>false</code> otherwise */ public static boolean hasValidator(JAXXCompiler compiler) { - List<CompiledBeanValidator> beanValidatorList = validators.get(compiler); + List<CompiledBeanValidator> beanValidatorList = + validators.get(compiler); return beanValidatorList != null && !beanValidatorList.isEmpty(); } @@ -730,9 +935,11 @@ * * @param compiler compiler to use * @param componentId the compiled object to test - * @return <code>true</code> if the given compiled object is attached to a validator, <code>false</code> otherwise + * @return <code>true</code> if the given compiled object is attached to + * a validator, <code>false</code> otherwise */ - public static boolean isComponentUsedByValidator(JAXXCompiler compiler, String componentId) { + public static boolean isComponentUsedByValidator(JAXXCompiler compiler, + String componentId) { List<String> ids = validatedComponents.get(compiler); return ids != null && ids.contains(componentId); } Added: trunk/jaxx-compiler/src/main/java/jaxx/compiler/tasks/CompileFirstPassTask.java =================================================================== --- trunk/jaxx-compiler/src/main/java/jaxx/compiler/tasks/CompileFirstPassTask.java (rev 0) +++ trunk/jaxx-compiler/src/main/java/jaxx/compiler/tasks/CompileFirstPassTask.java 2010-05-02 16:55:27 UTC (rev 1865) @@ -0,0 +1,139 @@ +/* + * #%L + * JAXX :: Compiler + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2008 - 2010 CodeLutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ +package jaxx.compiler.tasks; + +import jaxx.compiler.CompilerConfiguration; +import jaxx.compiler.JAXXCompiler; +import jaxx.compiler.JAXXCompilerFile; +import jaxx.compiler.JAXXEngine; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import java.io.File; + +/** + * First compile pass task to validate jaxx files and look after dependencies. + * + * @author tchemit <chemit@codelutin.com> + * @since 2.0.2 + */ +public class CompileFirstPassTask extends JAXXEngineTask { + + /** Logger */ + private static final Log log = LogFactory.getLog(CompileFirstPassTask.class); + + private static final long serialVersionUID = -1L; + + public static final String TASK_NAME = "CompileFirstPass"; + + public CompileFirstPassTask() { + super(TASK_NAME); + } + + protected boolean compiled; + + @Override + public boolean perform(JAXXEngine engine) throws Exception { + boolean success = true; + compiled = true; + while (compiled) { + + // at each round, says nothing has to be compiled + // the method treateFile will if required change the state + compiled = false; + + JAXXCompilerFile[] files = engine.getCompilingFiles(); + + for (JAXXCompilerFile jaxxFile : files) { + + boolean successForFile = treateFile(engine, jaxxFile); + + if (!successForFile) { + + // something is wrong... + success = false; + } + } + } + return success; + } + + protected boolean treateFile(JAXXEngine engine, + JAXXCompilerFile jaxxFile) throws Exception { + + boolean isVerbose = engine.isVerbose(); + + if (isVerbose) { + log.info(getName() + " for " + jaxxFile.getClassName()); + } + + JAXXCompiler compiler = jaxxFile.getCompiler(); + + if (compiler != null) { + + // file already registred + return true; + } + + boolean success = true; + + // mark to have another round to treate new files + compiled = true; + + CompilerConfiguration configuration = engine.getConfiguration(); + + compiler = engine.newCompiler(jaxxFile); + addStartProfileTime(engine, compiler); + + compiler.compileFirstPass(); + + if (configuration.isAutoImportCss() && !compiler.isIdentCssFound()) { + + // check if can add ident css file + + File cssFile = jaxxFile.getCssFile(); + + if (log.isDebugEnabled()) { + log.debug("test ident css file " + cssFile + " : " + isVerbose); + } + if (cssFile.exists()) { + + compiler.setIdentCssFound(true); + + if (isVerbose) { + log.info("Auto import of css " + cssFile); + } + // ok add it + compiler.registerStyleSheetFile(cssFile); + } + } + addEndProfileTime(engine, compiler); + + if (compiler.isFailed()) { + success = false; + } + return success; + } +} Property changes on: trunk/jaxx-compiler/src/main/java/jaxx/compiler/tasks/CompileFirstPassTask.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: trunk/jaxx-compiler/src/main/java/jaxx/compiler/tasks/CompileSecondPassTask.java =================================================================== --- trunk/jaxx-compiler/src/main/java/jaxx/compiler/tasks/CompileSecondPassTask.java (rev 0) +++ trunk/jaxx-compiler/src/main/java/jaxx/compiler/tasks/CompileSecondPassTask.java 2010-05-02 16:55:27 UTC (rev 1865) @@ -0,0 +1,103 @@ +/* + * #%L + * JAXX :: Compiler + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2008 - 2010 CodeLutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ +package jaxx.compiler.tasks; + +import jaxx.compiler.CompilerException; +import jaxx.compiler.JAXXCompiler; +import jaxx.compiler.JAXXCompilerFile; +import jaxx.compiler.JAXXEngine; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import java.util.Arrays; + +/** + * Task to execute the Second round of compile. + * + * @author tchemit <chemit@codelutin.com> + * @since 2.0.2 + */ +public class CompileSecondPassTask extends JAXXEngineTask { + + /** Logger */ + private static final Log log = + LogFactory.getLog(CompileSecondPassTask.class); + + private static final long serialVersionUID = -1L; + + public static final String TASK_NAME = "CompileSecondPass"; + + public CompileSecondPassTask() { + super(TASK_NAME); + } + + @Override + public boolean perform(JAXXEngine engine) throws Exception { + boolean success = true; + boolean isVerbose = engine.isVerbose(); + + JAXXCompilerFile[] files = engine.getCompilingFiles(); + + for (JAXXCompilerFile jaxxFile : files) { + + String className = jaxxFile.getClassName(); + if (isVerbose) { + log.info(getName() + " for " + className); + } + + JAXXCompiler compiler = getSafeCompiler(jaxxFile); + addStartProfileTime(engine, compiler); + if (log.isDebugEnabled()) { + log.debug("runInitializers for " + className); + } + if (!compiler.isFailed()) { + compiler.runInitializers(); + } + if (log.isDebugEnabled()) { + log.debug("compile second pass for " + className); + } + compiler.compileSecondPass(); + addEndProfileTime(engine, compiler); + if (log.isDebugEnabled()) { + log.debug("done with result [" + !compiler.isFailed() + + "] for " + className); + } + if (compiler.isFailed()) { + success = false; + } + } + + // check that compilation set was not altered during pass 2 + JAXXCompilerFile[] jaxxFilesClone = engine.getCompilingFiles(); + if (jaxxFilesClone.length > files.length) { + throw new CompilerException( + "Internal error: compilation set altered during pass" + + " 2 (was " + Arrays.toString(jaxxFilesClone) + + ", modified to " + Arrays.toString(files) + ")" + ); + } + return success; + } +} \ No newline at end of file Property changes on: trunk/jaxx-compiler/src/main/java/jaxx/compiler/tasks/CompileSecondPassTask.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: trunk/jaxx-compiler/src/main/java/jaxx/compiler/tasks/FinalizeTask.java =================================================================== --- trunk/jaxx-compiler/src/main/java/jaxx/compiler/tasks/FinalizeTask.java (rev 0) +++ trunk/jaxx-compiler/src/main/java/jaxx/compiler/tasks/FinalizeTask.java 2010-05-02 16:55:27 UTC (rev 1865) @@ -0,0 +1,74 @@ +/* + * #%L + * JAXX :: Compiler + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2008 - 2010 CodeLutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ +package jaxx.compiler.tasks; + +import jaxx.compiler.JAXXCompiler; +import jaxx.compiler.JAXXCompilerFile; +import jaxx.compiler.JAXXEngine; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * Task to execute after stylesheet tasks and juste before generation task. + * <p/> + * This task will finialize all compilers. + * + * @author tchemit <chemit@codelutin.com> + * @since 2.0.2 + */ +public class FinalizeTask extends JAXXEngineTask { + + /** Logger */ + private static final Log log = LogFactory.getLog(FinalizeTask.class); + + private static final long serialVersionUID = -1L; + + public static final String TASK_NAME = "Finalize"; + + public FinalizeTask() { + super(TASK_NAME); + } + + @Override + public boolean perform(JAXXEngine engine) throws Exception { + boolean success = true; + boolean isVerbose = engine.getConfiguration().isVerbose(); + + for (JAXXCompilerFile jaxxFile : engine.getCompilingFiles()) { + + if (isVerbose) { + log.info(getName() + " for " + jaxxFile.getClassName()); + } + JAXXCompiler compiler = getSafeCompiler(jaxxFile); + addStartProfileTime(engine, compiler); + compiler.finalizeCompiler(); + addEndProfileTime(engine, compiler); + if (compiler.isFailed()) { + success = false; + } + } + return success; + } +} \ No newline at end of file Property changes on: trunk/jaxx-compiler/src/main/java/jaxx/compiler/tasks/FinalizeTask.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: trunk/jaxx-compiler/src/main/java/jaxx/compiler/tasks/GenerateTask.java =================================================================== --- trunk/jaxx-compiler/src/main/java/jaxx/compiler/tasks/GenerateTask.java (rev 0) +++ trunk/jaxx-compiler/src/main/java/jaxx/compiler/tasks/GenerateTask.java 2010-05-02 16:55:27 UTC (rev 1865) @@ -0,0 +1,78 @@ +/* + * #%L + * JAXX :: Compiler + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2008 - 2010 CodeLutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ +package jaxx.compiler.tasks; + +import jaxx.compiler.JAXXCompiler; +import jaxx.compiler.JAXXCompilerFile; +import jaxx.compiler.JAXXEngine; +import jaxx.compiler.java.JavaFileGenerator; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * Last task to generate java files. + * + * @author tchemit <chemit@codelutin.com> + * @since 2.0.2 + */ +public class GenerateTask extends JAXXEngineTask { + + /** Logger */ + private static final Log log = LogFactory.getLog(GenerateTask.class); + + private static final long serialVersionUID = -1L; + + public static final String TASK_NAME = "Generate"; + + public GenerateTask() { + super(TASK_NAME); + } + + @Override + public boolean perform(JAXXEngine engine) throws Exception { + boolean success = true; + + boolean verbose = engine.isVerbose(); + + JavaFileGenerator generator = + new JavaFileGenerator(JAXXCompiler.getLineSeparator(), verbose); + + for (JAXXCompilerFile jaxxFile : engine.getCompilingFiles()) { + + if (verbose) { + log.info(getName() + " for " + jaxxFile.getClassName()); + } + + JAXXCompiler compiler = getSafeCompiler(jaxxFile); + addStartProfileTime(engine, compiler); + compiler.generate(generator); + addEndProfileTime(engine, compiler); + if (compiler.isFailed()) { + success = false; + } + } + return success; + } +} \ No newline at end of file Property changes on: trunk/jaxx-compiler/src/main/java/jaxx/compiler/tasks/GenerateTask.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: trunk/jaxx-compiler/src/main/java/jaxx/compiler/tasks/InitTask.java =================================================================== --- trunk/jaxx-compiler/src/main/java/jaxx/compiler/tasks/InitTask.java (rev 0) +++ trunk/jaxx-compiler/src/main/java/jaxx/compiler/tasks/InitTask.java 2010-05-02 16:55:27 UTC (rev 1865) @@ -0,0 +1,87 @@ +/* + * #%L + * JAXX :: Compiler + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2008 - 2010 CodeLutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ +package jaxx.compiler.tasks; + +import jaxx.compiler.CompilerConfiguration; +import jaxx.compiler.JAXXEngine; +import jaxx.compiler.JAXXFactory; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * The init task to be launched first. + * + * @author tchemit <chemit@codelutin.com> + * @since 2.0.2 + */ +public class InitTask extends JAXXEngineTask { + + private static final long serialVersionUID = -1L; + + public static final String TASK_NAME = "Init"; + + /** Logger */ + private static final Log log = LogFactory.getLog(InitTask.class); + + public InitTask() { + super(TASK_NAME); + } + + @Override + public boolean perform(JAXXEngine engine) throws Exception { + boolean success = true; + + CompilerConfiguration configuration = engine.getConfiguration(); + + // check initializers + if (configuration.getInitializers() == null) { + throw new NullPointerException( + "no initializers found in configuration."); + } + + // check decorators + if (configuration.getDecorators() == null) { + + throw new NullPointerException( + "no decorators found in configuration."); + } + + // check finalizers + if (configuration.getFinalizers() == null) { + + throw new NullPointerException( + "no finalizers found in configuration."); + } + + if (configuration.isVerbose()) { + log.info("will init " + JAXXFactory.class.getName()); + } + JAXXFactory.initFactory(); + + engine.clearReports(); + + return success; + } +} Property changes on: trunk/jaxx-compiler/src/main/java/jaxx/compiler/tasks/InitTask.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: trunk/jaxx-compiler/src/main/java/jaxx/compiler/tasks/JAXXEngineTask.java =================================================================== --- trunk/jaxx-compiler/src/main/java/jaxx/compiler/tasks/JAXXEngineTask.java (rev 0) +++ trunk/jaxx-compiler/src/main/java/jaxx/compiler/tasks/JAXXEngineTask.java 2010-05-02 16:55:27 UTC (rev 1865) @@ -0,0 +1,87 @@ +/* + * #%L + * JAXX :: Compiler + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2008 - 2010 CodeLutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ +package jaxx.compiler.tasks; + +import jaxx.compiler.CompilerException; +import jaxx.compiler.JAXXCompiler; +import jaxx.compiler.JAXXCompilerFile; +import jaxx.compiler.JAXXEngine; + +import java.io.Serializable; + +/** + * Base class to implement a task to be launched by a {@link JAXXEngine}. + * <p/> + * The {@link #perform(JAXXEngine)} method contains the logic of the task. + * + * @author tchemit <chemit@codelutin.com> + * @since 2.0.2 + */ +public abstract class JAXXEngineTask implements Serializable { + + private final String name; + + public JAXXEngineTask(String name) { + this.name = name; + } + + public abstract boolean perform(JAXXEngine engine) throws Exception; + + + public String getName() { + return name; + } + + protected void addStartProfileTime(JAXXEngine engine, + JAXXCompiler compiler) { + engine.addProfileTime(compiler, name + "_start"); + } + + protected void addEndProfileTime(JAXXEngine engine, + JAXXCompiler compiler) { + engine.addProfileTime(compiler, name + "_end"); + } + + protected JAXXCompiler getSafeCompiler(JAXXCompilerFile engine) { + JAXXCompiler compiler = engine.getCompiler(); + if (compiler == null) { + throw new CompilerException( + "Internal error: could not find compiler for " + + engine.getClassName() + " during task [" + getName() + "]" + ); + } + + return compiler; + } +// +// protected JAXXCompiler getSafeCompiler(JAXXEngine engine, +// String className) { +// JAXXCompiler compiler = engine.getCompiler( +// className, +// "Internal error: could not find compiler for " + className + +// " during task [" + getName() + "]"); +// return compiler; +// } +} Property changes on: trunk/jaxx-compiler/src/main/java/jaxx/compiler/tasks/JAXXEngineTask.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: trunk/jaxx-compiler/src/main/java/jaxx/compiler/tasks/ProfileTask.java =================================================================== --- trunk/jaxx-compiler/src/main/java/jaxx/compiler/tasks/ProfileTask.java (rev 0) +++ trunk/jaxx-compiler/src/main/java/jaxx/compiler/tasks/ProfileTask.java 2010-05-02 16:55:27 UTC (rev 1865) @@ -0,0 +1,57 @@ +/* + * #%L + * JAXX :: Compiler + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2008 - 2010 CodeLutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ +package jaxx.compiler.tasks; + +import jaxx.compiler.JAXXEngine; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * A task to display result of profile mode + * + * @author tchemit <chemit@codelutin.com> + * @since 2.0.2 + */ +public class ProfileTask extends JAXXEngineTask { + + /** Logger */ + private static final Log log = LogFactory.getLog(ProfileTask.class); + + private static final long serialVersionUID = -1L; + + public static final String TASK_NAME = "Profile"; + + public ProfileTask() { + super(TASK_NAME); + } + + @Override + public boolean perform(JAXXEngine engine) throws Exception { + boolean success = true; + StringBuilder buffer = engine.getProfiler().computeProfileReport(); + log.info(buffer.toString()); + return success; + } +} \ No newline at end of file Property changes on: trunk/jaxx-compiler/src/main/java/jaxx/compiler/tasks/ProfileTask.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: trunk/jaxx-compiler/src/main/java/jaxx/compiler/tasks/StyleSheetTask.java =================================================================== --- trunk/jaxx-compiler/src/main/java/jaxx/compiler/tasks/StyleSheetTask.java (rev 0) +++ trunk/jaxx-compiler/src/main/java/jaxx/compiler/tasks/StyleSheetTask.java 2010-05-02 16:55:27 UTC (rev 1865) @@ -0,0 +1,73 @@ +/* + * #%L + * JAXX :: Compiler + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2008 - 2010 CodeLutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ +package jaxx.compiler.tasks; + +import jaxx.compiler.JAXXCompiler; +import jaxx.compiler.JAXXCompilerFile; +import jaxx.compiler.JAXXEngine; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * Task to apply css stylesheet on objects after second round of compilation. + * + * @author tchemit <chemit@codelutin.com> + * @since 2.0.2 + */ +public class StyleSheetTask extends JAXXEngineTask { + + /** Logger */ + private static final Log log = LogFactory.getLog(StyleSheetTask.class); + + private static final long serialVersionUID = -1L; + + public static final String TASK_NAME = "StyleSheet"; + + public StyleSheetTask() { + super(TASK_NAME); + } + + @Override + public boolean perform(JAXXEngine engine) throws Exception { + boolean success = true; + boolean isVerbose = engine.getConfiguration().isVerbose(); + JAXXCompilerFile[] files = engine.getCompilingFiles(); + for (JAXXCompilerFile jaxxFile : files) { + String className = jaxxFile.getClassName(); + if (isVerbose) { + log.info(getName() + " for " + className); + } + JAXXCompiler compiler = getSafeCompiler(jaxxFile); + addStartProfileTime(engine, compiler); + compiler.applyStylesheets(); + addEndProfileTime(engine, compiler); + if (compiler.isFailed()) { + success = false; + } + } + return success; + } + +} \ No newline at end of file Property changes on: trunk/jaxx-compiler/src/main/java/jaxx/compiler/tasks/StyleSheetTask.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Modified: trunk/jaxx-compiler/src/main/java/jaxx/compiler/tools/PrintTagInfo.java =================================================================== --- trunk/jaxx-compiler/src/main/java/jaxx/compiler/tools/PrintTagInfo.java 2010-05-02 11:04:42 UTC (rev 1864) +++ trunk/jaxx-compiler/src/main/java/jaxx/compiler/tools/PrintTagInfo.java 2010-05-02 16:55:27 UTC (rev 1865) @@ -25,9 +25,10 @@ package jaxx.compiler.tools; +import jaxx.compiler.DefaultCompilerConfiguration; +import jaxx.compiler.JAXXFactory; import jaxx.compiler.tags.*; import jaxx.compiler.JAXXCompiler; -import jaxx.compiler.JAXXEngine; import jaxx.compiler.beans.JAXXPropertyDescriptor; import jaxx.compiler.reflect.ClassDescriptor; import jaxx.compiler.reflect.ClassDescriptorLoader; @@ -61,7 +62,8 @@ } try { - JAXXEngine.loadLibraries(false); + JAXXFactory.setConfiguration(new DefaultCompilerConfiguration()); + JAXXFactory.initFactory(); for (int i = toFile ? 1 : 0; i < arg.length; i++) { String className = arg[i]; treateClass(w, className); Modified: trunk/jaxx-compiler/src/test/java/jaxx/compiler/tags/TagManagerTest.java =================================================================== --- trunk/jaxx-compiler/src/test/java/jaxx/compiler/tags/TagManagerTest.java 2010-05-02 11:04:42 UTC (rev 1864) +++ trunk/jaxx-compiler/src/test/java/jaxx/compiler/tags/TagManagerTest.java 2010-05-02 16:55:27 UTC (rev 1865) @@ -25,8 +25,10 @@ package jaxx.compiler.tags; +import jaxx.compiler.CompilerConfiguration; +import jaxx.compiler.DefaultCompilerConfiguration; import jaxx.compiler.JAXXCompiler; -import jaxx.compiler.JAXXEngine; +import jaxx.compiler.JAXXFactory; import jaxx.compiler.reflect.ClassDescriptor; import jaxx.compiler.reflect.ClassDescriptorLoader; import org.junit.Assert; @@ -43,6 +45,8 @@ public class TagManagerTest { + protected static CompilerConfiguration configuration; + protected JAXXCompiler compiler; public static class TestHandler extends DefaultObjectHandler { @@ -53,16 +57,20 @@ } @BeforeClass - public static void initTagManaer() throws Exception { + public static void init() throws Exception { + if (configuration == null) { + configuration = new DefaultCompilerConfiguration(); + } +// TagManager.reset(); + JAXXFactory.setConfiguration(configuration); + JAXXFactory.initFactory(); - TagManager.reset(true); - } @Before public void setUp() { - JAXXEngine.newLaunchor(); - compiler = JAXXEngine.createDummyCompiler(JAXXCompiler.class.getClassLoader()); + JAXXFactory.newDummyEngine(); + compiler = JAXXFactory.newDummyCompiler(JAXXCompiler.class.getClassLoader()); // compiler = new JAXXCompiler(JAXXCompiler.class.getClassLoader()); compiler.addImport("javax.swing.*"); @@ -129,7 +137,7 @@ ByteArrayOutputStream buffer = new ByteArrayOutputStream(); System.setErr(new PrintStream(buffer)); compiler.addImport("java.util.*"); - TagManager.reset(true); + init(); Assert.assertNull("Still found a handler for Date with an ambiguous import", TagManager.getTagHandler(null, "Date", compiler)); System.setErr(oldErr); Assert.assertTrue("No errors were produced with an ambiguous import", buffer.size() > 0); Modified: trunk/jaxx-demo/src/site/rst/index.rst =================================================================== --- trunk/jaxx-demo/src/site/rst/index.rst 2010-05-02 11:04:42 UTC (rev 1864) +++ trunk/jaxx-demo/src/site/rst/index.rst 2010-05-02 16:55:27 UTC (rev 1865) @@ -1,23 +1,23 @@ .. - .. * #%L .. * JAXX :: Demo -.. * +.. * .. * $Id$ .. * $HeadURL$ .. * %% .. * Copyright (C) 2008 - 2010 CodeLutin .. * %% .. * This program is free software: you can redistribute it and/or modify -.. * it under the terms of the GNU Lesser General Public License as -.. * published by the Free Software Foundation, either version 3 of the +.. * it under the terms of the GNU Lesser General Public License as +.. * published by the Free Software Foundation, either version 3 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 Lesser Public License for more details. -.. * -.. * You should have received a copy of the GNU General Lesser Public +.. * +.. * You should have received a copy of the GNU General Lesser Public .. * License along with this program. If not, see .. * <http://www.gnu.org/licenses/lgpl-3.0.html>. .. * #L% Modified: trunk/maven-jaxx-plugin/src/main/java/org/nuiton/jaxx/plugin/GenerateMojo.java =================================================================== --- trunk/maven-jaxx-plugin/src/main/java/org/nuiton/jaxx/plugin/GenerateMojo.java 2010-05-02 11:04:42 UTC (rev 1864) +++ trunk/maven-jaxx-plugin/src/main/java/org/nuiton/jaxx/plugin/GenerateMojo.java 2010-05-02 16:55:27 UTC (rev 1865) @@ -25,11 +25,17 @@ package org.nuiton.jaxx.plugin; -import jaxx.compiler.*; +import jaxx.compiler.CompiledObjectDecorator; +import jaxx.compiler.CompilerConfiguration; +import jaxx.compiler.I18nHelper; +import jaxx.compiler.JAXXCompiler; +import jaxx.compiler.JAXXCompilerFinalizer; +import jaxx.compiler.JAXXEngine; +import jaxx.compiler.JAXXFactory; import jaxx.compiler.beans.BeanInfoUtil; import jaxx.compiler.binding.DataBindingHelper; import jaxx.compiler.spi.DefaultInitializer; -import jaxx.compiler.tags.TagManager; +import jaxx.compiler.spi.Initializer; import jaxx.runtime.JAXXContext; import jaxx.runtime.JAXXObject; import jaxx.runtime.swing.help.JAXXHelpBroker; @@ -42,7 +48,12 @@ import java.beans.Introspector; import java.io.File; -import java.util.*; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; /** * Generates some java code from jaxx files. @@ -212,11 +223,10 @@ /** * To let jaxx recurses in css when a JAXX Object auto import css files * for a jaxx file. - * + * <p/> * <b>Warning:</b> This option will be removed in version 3.0 or at least * default value will become {@code false}. * - * * @parameter expression="${jaxx.autoRecurseInCss}" default-value="true" * @since 2.0.2 */ @@ -308,14 +318,10 @@ */ protected MirroredFileUpdater updater; - /** - * - */ + /** type of error ui class (in validation) to use */ private Class<?> defaultErrorUIClass; - /** - * - */ + /** type of validator to use */ private Class<?> validatorClass; /** type of {@link CompiledObjectDecorator} to use */ @@ -327,19 +333,39 @@ /** type of compiler to use */ private Class<? extends JAXXCompiler> compilerClass; - /** - * - */ + /** extra imports to always add in each generated java file */ private String[] extraImports; /** internal state to known if a files has to be generated */ private boolean nofiles; + /** customized classloader to use in engine */ + protected ClassLoader cl; + /** + * decorators available in engine. * + * @component role="jaxx.compiler.CompiledObjectDecorator" + * @since 2.0.2 */ - protected ClassLoader cl; + protected Map<String, CompiledObjectDecorator> decorators; + /** + * finalizers available in engine. + * + * @component role="jaxx.compiler.JAXXCompilerFinalizer" + * @since 2.0.2 + */ + protected Map<String, JAXXCompilerFinalizer> finalizers; + + /** + * initializers availables to init engine. + * + * @component role="jaxx.compiler.spi.Initializer" + * @since 2.0.2 + */ + protected Map<String, Initializer> initializers; + /** JAXX engine */ private JAXXEngine engine; @@ -453,7 +479,7 @@ } if (isVerbose()) { - getLog().info(toString()); +// getLog().info(toString()); getLog().info("includes : " + Arrays.toString(includes)); for (String file : files) { getLog().info("will parse " + file); @@ -481,31 +507,25 @@ try { long t0 = System.nanoTime(); - // force compiler init from here, not in a static block - TagManager.reset(isVerbose()); + // register configuration to factory + JAXXFactory.setConfiguration(this); - engine = JAXXEngine.newLaunchor(src, files, this); + // create new engine + engine = JAXXFactory.newEngine(src, files); + + //FIXME-TC20100502 remove this managment by -1 for error! + // run engine int nbFiles = engine.run(); + + // report engine results (errors, warnings,...) report(engine); + if (nbFiles == -1) { throw new MojoExecutionException( "Aborting due to errors reported by jaxxc"); } - getLog().info("Generated " + nbFiles + " file(s) in " + - PluginHelper.convertTime(System.nanoTime() - t0)); - - } catch (MojoExecutionException e) { - getLog().error(e); - throw e; - } catch (Exception e) { - //getLog().error(e); - Throwable e2 = e; - while (e2.getCause() != null) { - e2 = e.getCause(); - } - getLog().error(e2); - - throw new MojoExecutionException(e2.getMessage(), e2); + String delay = PluginHelper.convertTime(System.nanoTime() - t0); + getLog().info("Generated " + nbFiles + " file(s) in " + delay); } finally { DataBindingHelper.SHOW_LOG = false; } @@ -611,6 +631,21 @@ return validatorClass; } + @Override + public Map<String, CompiledObjectDecorator> getDecorators() { + return decorators; + } + + @Override + public Map<String, JAXXCompilerFinalizer> getFinalizers() { + return finalizers; + } + + @Override + public Map<String, Initializer> getInitializers() { + return initializers; + } + public JAXXEngine getEngine() { return engine; } Modified: trunk/maven-jaxx-plugin/src/test/java/org/nuiton/jaxx/plugin/JaxxBaseTest.java =================================================================== --- trunk/maven-jaxx-plugin/src/test/java/org/nuiton/jaxx/plugin/JaxxBaseTest.java 2010-05-02 11:04:42 UTC (rev 1864) +++ trunk/maven-jaxx-plugin/src/test/java/org/nuiton/jaxx/plugin/JaxxBaseTest.java 2010-05-02 16:55:27 UTC (rev 1865) @@ -25,24 +25,25 @@ package org.nuiton.jaxx.plugin; +import jaxx.compiler.JAXXCompiler; +import jaxx.compiler.JAXXCompilerFile; +import jaxx.compiler.JAXXEngine; import jaxx.compiler.decorators.DefaultCompiledObjectDecorator; import jaxx.runtime.context.DefaultJAXXContext; import jaxx.runtime.validator.swing.SwingValidator; +import org.nuiton.plugin.AbstractMojoTest; import org.nuiton.util.FileUtil; import java.io.File; import java.io.IOException; -import java.lang.reflect.Field; import java.util.List; -import java.util.Map; -import jaxx.compiler.JAXXCompiler; -import jaxx.compiler.JAXXEngine; -import org.nuiton.plugin.AbstractMojoTest; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + /** * Base test case for a jaxx:generate goal. - * + * <p/> * Use {@link AbstractMojoTest} from {@code maven-helper-plugin}. * * @author tchemit <chemit@codelutin.com> @@ -51,8 +52,6 @@ */ public abstract class JaxxBaseTest extends AbstractMojoTest<GenerateMojo> { - private Field fieldCompilers; - @Override protected String getGoalName(String methodName) { return "generate"; @@ -71,7 +70,7 @@ mojo.compilerFQN = JAXXCompiler.class.getName(); mojo.validatorFQN = SwingValidator.class.getName(); mojo.defaultDecoratorFQN = DefaultCompiledObjectDecorator.class.getName(); - + } protected void checkPattern(GenerateMojo mojo, String pattern, boolean required, String... files) throws IOException { @@ -103,15 +102,10 @@ @SuppressWarnings("unchecked") protected void assertError(JAXXEngine engine, String file, int nbCompiler) throws Exception { - if (fieldCompilers == null) { - fieldCompilers = JAXXEngine.class.getDeclaredField("compilers"); - fieldCompilers.setAccessible(true); - } - Map<String, JAXXCompiler> compilers = (Map<String, JAXXCompiler>) fieldCompilers.get(engine); - assertEquals(nbCompiler, compilers.size()); + JAXXCompilerFile[] compilers = engine.getCompilingFiles(); + assertEquals(nbCompiler, compilers.length); List<String> errors = engine.getErrors(); - //Integer nberrors = (Integer) fieldErrorCount.get(launchor); assertTrue("should have found at least one error for " + file, errors != null && !errors.isEmpty()); } } Modified: trunk/src/site/rst/JAXXFile.rst =================================================================== --- trunk/src/site/rst/JAXXFile.rst 2010-05-02 11:04:42 UTC (rev 1864) +++ trunk/src/site/rst/JAXXFile.rst 2010-05-02 16:55:27 UTC (rev 1865) @@ -1,3 +1,27 @@ +.. - +.. * #%L +.. * JAXX +.. * +.. * $Id$ +.. * $HeadURL$ +.. * %% +.. * Copyright (C) 2008 - 2010 CodeLutin +.. * %% +.. * This program is free software: you can redistribute it and/or modify +.. * it under the terms of the GNU Lesser General Public License as +.. * published by the Free Software Foundation, either version 3 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 Lesser Public License for more details. +.. * +.. * You should have received a copy of the GNU General Lesser Public +.. * License along with this program. If not, see +.. * <http://www.gnu.org/licenses/lgpl-3.0.html>. +.. * #L% +.. - ============================== Qu'est-ce qu'un fichier JAXX ? ============================== Modified: trunk/src/site/rst/dataBinding.rst =================================================================== --- trunk/src/site/rst/dataBinding.rst 2010-05-02 11:04:42 UTC (rev 1864) +++ trunk/src/site/rst/dataBinding.rst 2010-05-02 16:55:27 UTC (rev 1865) @@ -1,3 +1,27 @@ +.. - +.. * #%L +.. * JAXX +.. * +.. * $Id$ +.. * $HeadURL$ +.. * %% +.. * Copyright (C) 2008 - 2010 CodeLutin +.. * %% +.. * This program is free software: you can redistribute it and/or modify +.. * it under the terms of the GNU Lesser General Public License as +.. * published by the Free Software Foundation, either version 3 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 Lesser Public License for more details. +.. * +.. * You should have received a copy of the GNU General Lesser Public +.. * License along with this program. If not, see +.. * <http://www.gnu.org/licenses/lgpl-3.0.html>. +.. * #L% +.. - ======================== Utiliser le data-binding ======================== Modified: trunk/src/site/rst/presentation.rst =================================================================== --- trunk/src/site/rst/presentation.rst 2010-05-02 11:04:42 UTC (rev 1864) +++ trunk/src/site/rst/presentation.rst 2010-05-02 16:55:27 UTC (rev 1865) @@ -1,3 +1,27 @@ +.. - +.. * #%L +.. * JAXX +.. * +.. * $Id$ +.. * $HeadURL$ +.. * %% +.. * Copyright (C) 2008 - 2010 CodeLutin +.. * %% +.. * This program is free software: you can redistribute it and/or modify +.. * it under the terms of the GNU Lesser General Public License as +.. * published by the Free Software Foundation, either version 3 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 Lesser Public License for more details. +.. * +.. * You should have received a copy of the GNU General Lesser Public +.. * License along with this program. If not, see +.. * <http://www.gnu.org/licenses/lgpl-3.0.html>. +.. * #L% +.. - ============ Présentation ============ Modified: trunk/src/site/rst/useStylesheets.rst =================================================================== --- trunk/src/site/rst/useStylesheets.rst 2010-05-02 11:04:42 UTC (rev 1864) +++ trunk/src/site/rst/useStylesheets.rst 2010-05-02 16:55:27 UTC (rev 1865) @@ -1,3 +1,27 @@ +.. - +.. * #%L +.. * JAXX +.. * +.. * $Id$ +.. * $HeadURL$ +.. * %% +.. * Copyright (C) 2008 - 2010 CodeLutin +.. * %% +.. * This program is free software: you can redistribute it and/or modify +.. * it under the terms of the GNU Lesser General Public License as +.. * published by the Free Software Foundation, either version 3 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 Lesser Public License for more details. +.. * +.. * You should have received a copy of the GNU General Lesser Public +.. * License along with this program. If not, see +.. * <http://www.gnu.org/licenses/lgpl-3.0.html>. +.. * #L% +.. - =================== Utiliser des styles =================== Modified: trunk/src/site/rst/useSwingObjects.rst =================================================================== --- trunk/src/site/rst/useSwingObjects.rst 2010-05-02 11:04:42 UTC (rev 1864) +++ trunk/src/site/rst/useSwingObjects.rst 2010-05-02 16:55:27 UTC (rev 1865) @@ -1,3 +1,27 @@ +.. - +.. * #%L +.. * JAXX +.. * +.. * $Id$ +.. * $HeadURL$ +.. * %% +.. * Copyright (C) 2008 - 2010 CodeLutin +.. * %% +.. * This program is free software: you can redistribute it and/or modify +.. * it under the terms of the GNU Lesser General Public License as +.. * published by the Free Software Foundation, either version 3 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 Lesser Public License for more details. +.. * +.. * You should have received a copy of the GNU General Lesser Public +.. * License along with this program. If not, see +.. * <http://www.gnu.org/licenses/lgpl-3.0.html>. +.. * #L% +.. - ========================= Utiliser les objets Swing =========================
participants (1)
-
tchemit@users.nuiton.org