Author: tchemit Date: 2009-10-25 20:48:54 +0100 (Sun, 25 Oct 2009) New Revision: 1594 Added: branches/jaxx-2.X/jaxx-compiler/src/main/java/jaxx/compiler/finalizers/ branches/jaxx-2.X/jaxx-compiler/src/main/java/jaxx/compiler/finalizers/DefaultFinalizer.java branches/jaxx-2.X/jaxx-compiler/src/main/java/jaxx/compiler/finalizers/SwingFinalizer.java branches/jaxx-2.X/jaxx-compiler/src/main/java/jaxx/compiler/finalizers/ValidatorFinalizer.java Removed: branches/jaxx-2.X/jaxx-compiler/src/main/java/jaxx/compiler/finalizers/Generator.java branches/jaxx-2.X/jaxx-compiler/src/main/java/jaxx/compiler/finalizers/GeneratorManager.java branches/jaxx-2.X/jaxx-compiler/src/main/java/jaxx/compiler/finalizers/JAXXObjectGenerator.java branches/jaxx-2.X/jaxx-compiler/src/main/java/jaxx/compiler/finalizers/SwingGenerator.java branches/jaxx-2.X/jaxx-compiler/src/main/java/jaxx/compiler/finalizers/ValidatorGenerator.java branches/jaxx-2.X/jaxx-compiler/src/main/java/jaxx/compiler/generators/ branches/jaxx-2.X/jaxx-compiler/src/main/java/jaxx/compiler/io/ branches/jaxx-2.X/jaxx-compiler/src/main/java/jaxx/compiler/parser/ Log: - Evolution #100: am?\195?\169lioration du design du compilateur - Evolution #99: Am?\195?\169liorer le code g?\195?\169n?\195?\169r?\195?\169 - amelioration des test dans le plugin Property changes on: branches/jaxx-2.X/jaxx-compiler/src/main/java/jaxx/compiler/finalizers ___________________________________________________________________ Added: svn:mergeinfo + Copied: branches/jaxx-2.X/jaxx-compiler/src/main/java/jaxx/compiler/finalizers/DefaultFinalizer.java (from rev 1582, branches/jaxx-2.X/jaxx-compiler/src/main/java/jaxx/compiler/generators/JAXXObjectGenerator.java) =================================================================== --- branches/jaxx-2.X/jaxx-compiler/src/main/java/jaxx/compiler/finalizers/DefaultFinalizer.java (rev 0) +++ branches/jaxx-2.X/jaxx-compiler/src/main/java/jaxx/compiler/finalizers/DefaultFinalizer.java 2009-10-25 19:48:54 UTC (rev 1594) @@ -0,0 +1,530 @@ +package jaxx.compiler.finalizers; + +import jaxx.compiler.JAXXCompilerFinalizer; +import jaxx.compiler.CompilerException; +import jaxx.compiler.CompiledObject; +import jaxx.compiler.CompiledObjectDecorator; +import jaxx.compiler.DataBinding; +import jaxx.compiler.EventHandler; +import jaxx.compiler.JAXXCompiler; +import jaxx.compiler.java.JavaMethod; +import jaxx.compiler.java.JavaArgument; +import jaxx.compiler.java.JavaField; +import jaxx.compiler.java.JavaFile; +import jaxx.compiler.reflect.ClassDescriptor; +import jaxx.compiler.reflect.ClassDescriptorLoader; +import jaxx.compiler.reflect.FieldDescriptor; +import jaxx.compiler.reflect.MethodDescriptor; +import jaxx.runtime.Base64Coder; +import jaxx.runtime.JAXXObject; +import jaxx.runtime.JAXXObjectDescriptor; +import jaxx.runtime.JAXXContext; +import jaxx.runtime.Util; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import java.io.IOException; +import static java.lang.reflect.Modifier.*; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import static jaxx.compiler.java.JavaFileGenerator.*; + +/** + * This class is a refactoring of the {@link jaxx.compiler.JAXXCompiler}. + * <p/> + * We delegate now the generation of a {@link jaxx.runtime.JAXXObject} to this class, the + * {@link jaxx.compiler.JAXXCompiler} now only deals with the compilation of files. + * + * @author chemit + */ +public class DefaultFinalizer implements JAXXCompilerFinalizer { + + /** log */ + protected static final Log log = LogFactory.getLog(DefaultFinalizer.class); + protected static final JavaField SERIAL_VERSION_UID_FIELD = newField(PRIVATE | STATIC | FINAL, + "long", "serialVersionUID", false, "1L"); + protected static final JavaField ACTIVE_BINDINGS_FIELD = newField(PROTECTED, + "java.util.List<Object>", "$activeBindings", false, "new ArrayList<Object>()"); + protected static final JavaField BINDING_SOURCES_FIELD = newField(PROTECTED, + "java.util.Map<String,Object>", "$bindingSources", false, "new HashMap<String,Object>()"); + protected static final JavaField OBJECT_MAP_FIELD = newField(PROTECTED, + "Map<String,Object>", "$objectMap", true, "new HashMap<String,Object>()"); + protected static final JavaField ALL_COMPONENTS_CREATED_FIELD = newField(PRIVATE, + "boolean", "allComponentsCreated", false); + protected static final JavaField CONTEXT_INITIALIZED = newField(PRIVATE, + "boolean", "contextInitialized", false, "true"); + protected static final JavaField PREVIOUS_VALUES_FIELD = newField(PROTECTED, + "java.util.Map<?,?>", "$previousValues", false, "new java.util.HashMap<Object,Object>()"); + protected static final JavaField DELEGATE_CONTEXT_FIELD = newField(PROTECTED, + JAXXContext.class.getName(), "delegateContext", true); + protected static final JavaField PROPERTY_CHANGE_SUPPORT_FIELD = newField(0, + "java.beans.PropertyChangeSupport", "$propertyChangeSupport", false); + protected static final JavaMethod GET_CONTEXT_VALUE_METHOD = newMethod(PUBLIC, "<T> T", "getContextValue", + "return delegateContext.getContextValue(clazz, null);", true, + new JavaArgument("Class<T>", "clazz")); + protected static final JavaMethod GET_CONTEXT_VALUE_NAMED_METHOD = newMethod(PUBLIC, "<T> T", "getContextValue", + "return delegateContext.getContextValue(clazz, name);", true, + new JavaArgument("Class<T>", "clazz"), new JavaArgument("String", "name")); + protected static final JavaMethod SET_CONTEXT_VALUE_NAMED_METHOD = newMethod(PUBLIC, "<T> void", "setContextValue", + "delegateContext.setContextValue(o, name);", true, + new JavaArgument("T", "o"), new JavaArgument("String", "name")); + protected static final JavaMethod SET_CONTEXT_VALUE_METHOD = newMethod(PUBLIC, "<T> void", "setContextValue", + "delegateContext.setContextValue(o, null);", true, + new JavaArgument("T", "o")); + protected static final JavaMethod REMOVE_CONTEXT_VALUE_NAMED_METHOD = newMethod(PUBLIC, "<T> void", "removeContextValue", + "delegateContext.removeContextValue(clazz, name);", true, + new JavaArgument("Class<T>", "clazz"), new JavaArgument("String", "name")); + protected static final JavaMethod REMOVE_CONTEXT_VALUE_METHOD = newMethod(PUBLIC, "<T> void", "removeContextValue", + "delegateContext.removeContextValue(clazz, null);", true, + new JavaArgument("Class<T>", "clazz")); + protected static final JavaMethod GET_PARENT_CONTAINER_MORE_METHOD = newMethod(PUBLIC, "<O extends Container> O", "getParentContainer", + "return delegateContext.getParentContainer(source, clazz);", true, + new JavaArgument("Object", "source"), new JavaArgument("Class<O>", "clazz")); + protected static final JavaMethod GET_PARENT_CONTAINER_METHOD = newMethod(PUBLIC, "<O extends Container> O", "getParentContainer", + "return delegateContext.getParentContainer(clazz);", true, + new JavaArgument("Class<O>", "clazz")); + protected static final JavaMethod GET_OBJECT_BY_ID_METHOD = newMethod(PUBLIC, "java.lang.Object", "getObjectById", + "return $objectMap.get(id);", true, + new JavaArgument("String", "id")); + protected static final JavaMethod GET_JAXX_OBJECT_DESCRIPTOR_METHOD = newMethod(PUBLIC | STATIC, "jaxx.runtime.JAXXObjectDescriptor", "$getJAXXObjectDescriptor", + "return jaxx.runtime.Util.decodeCompressedJAXXObjectDescriptor($jaxxObjectDescriptor);", false); + protected static final JavaMethod PROCESS_DATA_BINDING_METHOD = newMethod(PUBLIC, "void", "processDataBinding", + "processDataBinding(dest, false);", true, + new JavaArgument("String", "dest")); + protected static final JavaMethod FIRE_PROPERTY_CHANGE_METHOD = newMethod(PUBLIC, "void", "firePropertyChange", + "super.firePropertyChange(propertyName, oldValue, newValue);", true, + new JavaArgument("String", "propertyName"), new JavaArgument("Object", "oldValue"), new JavaArgument("Object", "newValue")); + protected static final JavaMethod FIRE_PROPERTY_CHANGE_NAMED_METHOD = newMethod(PUBLIC, "void", "firePropertyChange", + "$getPropertyChangeSupport().firePropertyChange(propertyName, oldValue, newValue);", true, + new JavaArgument("String", "propertyName"), new JavaArgument("Object", "oldValue"), new JavaArgument("Object", "newValue")); + protected static final JavaMethod GET_PROPERTY_CHANGE_SUPPORT_METHOD = newMethod(0, "java.beans.PropertyChangeSupport", "$getPropertyChangeSupport", + "if ($propertyChangeSupport == null)\n" + + " $propertyChangeSupport = new PropertyChangeSupport(this);\n" + + "return $propertyChangeSupport;", false); + protected static final JavaMethod ADD_PROPERTY_CHANGE_SUPPORT_METHOD = newMethod(PUBLIC, "void", "addPropertyChangeListener", + "$getPropertyChangeSupport().addPropertyChangeListener(listener);", true, + new JavaArgument("java.beans.PropertyChangeListener", "listener")); + protected static final JavaMethod ADD_PROPERTY_CHANGE_SUPPORT_NAMED_METHOD = newMethod(PUBLIC, "void", "addPropertyChangeListener", + "$getPropertyChangeSupport().addPropertyChangeListener(property, listener);", true, + new JavaArgument("String", "property"), new JavaArgument("java.beans.PropertyChangeListener", "listener")); + protected static final JavaMethod REMOVE_PROPERTY_CHANGE_SUPPORT_METHOD = newMethod(PUBLIC, "void", "removePropertyChangeListener", + "$getPropertyChangeSupport().removePropertyChangeListener(listener);", true, + new JavaArgument("java.beans.PropertyChangeListener", "listener")); + protected static final JavaMethod REMOVE_PROPERTY_CHANGE_SUPPORT_NAMED_METHOD = newMethod(PUBLIC, "void", "removePropertyChangeListener", + "$getPropertyChangeSupport().removePropertyChangeListener(property, listener);", true, + new JavaArgument("String", "property"), new JavaArgument("java.beans.PropertyChangeListener", "listener")); + + @Override + public void finalizeCompiler(CompiledObject root, JAXXCompiler compiler, JavaFile javaFile, String packageName, String className) { + + String fullClassName = packageName != null ? packageName + "." + className : className; + if (root == null) { + throw new CompilerException("root tag must be a class tag"); + } + //Map<String, CompiledObject> objects = compiler.getObjects(); + ClassDescriptor superclass = root.getObjectClass(); + boolean superclassIsJAXXObject = ClassDescriptorLoader.getClassDescriptor(JAXXObject.class).isAssignableFrom(superclass); + javaFile.setModifiers(PUBLIC); + javaFile.setName(fullClassName); + javaFile.setSuperClass(JAXXCompiler.getCanonicalName(superclass)); + javaFile.setSuperclassIsJAXXObject(superclassIsJAXXObject); + + javaFile.addInterfaces(compiler.getExtraInterfaces()); + javaFile.setAbstractClass(compiler.isAbstractClass()); + javaFile.setGenericType(compiler.getGenericType()); + javaFile.setSuperGenericType(compiler.getSuperGenericType()); + + // finalize all objects via their decorator + for (CompiledObject object : compiler.getObjects().values()) { + CompiledObjectDecorator decorator = object.getDecorator(); + decorator.finalizeCompiler(compiler, root, object, javaFile, packageName, className, fullClassName); + } + String eol = JAXXCompiler.getLineSeparator(); + + // DataBinding + for (DataBinding dataBinding : compiler.getDataBindings()) { + if (dataBinding.compile(true)) { + compiler.getInitDataBindings().append("applyDataBinding(").append(compiler.getJavaCode(dataBinding.getId())).append(");").append(eol); + } + } + + if (superclassIsJAXXObject) { +// boolean hasBind = compiler.getApplyDataBinding().length() > 0; + boolean hasBind = compiler.hasApplyDataBinding(); + if (hasBind) { + compiler.appendApplyDataBinding(" else {"); + compiler.appendApplyDataBinding(eol); + compiler.appendApplyDataBinding(" "); + } + compiler.appendApplyDataBinding("super.applyDataBinding($binding);"); + compiler.appendApplyDataBinding(eol); + + if (hasBind) { + compiler.appendApplyDataBinding(" return;"); + compiler.appendApplyDataBinding(eol); + compiler.appendApplyDataBinding("}"); + } + + hasBind = compiler.hasRemoveDataBinding(); +// hasBind = compiler.getRemoveDataBinding().length() > 0; + if (hasBind) { + compiler.appendRemoveDataBinding(" else {"); + compiler.appendRemoveDataBinding(eol); + compiler.appendRemoveDataBinding(" "); + } + compiler.appendRemoveDataBinding("super.removeDataBinding($binding);"); + compiler.appendRemoveDataBinding(eol); + + if (hasBind) { + compiler.appendRemoveDataBinding("}"); + } + } else { + javaFile.addInterface(JAXXCompiler.getCanonicalName(JAXXObject.class)); + } + } + + @Override + public void prepareJavaFile(CompiledObject root, JAXXCompiler compiler, JavaFile javaFile, String packageName, String className) throws ClassNotFoundException { + + String fullClassName = javaFile.getName(); + + String jaxxContextImplementorClass = compiler.getConfiguration().getJaxxContextClass().getName(); + boolean superclassIsJAXXObject = javaFile.isSuperclassIsJAXXObject(); + if (!superclassIsJAXXObject) { + // add logger + if (compiler.getConfiguration().isAddLogger()) { + javaFile.addImport(Log.class); + javaFile.addImport(LogFactory.class); + javaFile.addSimpleField(newField(PUBLIC | STATIC | FINAL, "Log", "log", false, "LogFactory.getLog(" + fullClassName + ".class)")); + } + + // JAXXObject + javaFile.addField(OBJECT_MAP_FIELD); + javaFile.addMethod(GET_OBJECT_BY_ID_METHOD); + javaFile.addField(BINDING_SOURCES_FIELD); + javaFile.addField(ACTIVE_BINDINGS_FIELD); + + // JAXXContext + javaFile.addField(newField(PROTECTED | FINAL, JAXXContext.class.getName(), "delegateContext", true, "new " + jaxxContextImplementorClass + "(this);")); + javaFile.addMethod(SET_CONTEXT_VALUE_METHOD); + javaFile.addMethod(SET_CONTEXT_VALUE_NAMED_METHOD); + javaFile.addMethod(GET_CONTEXT_VALUE_METHOD); + javaFile.addMethod(GET_CONTEXT_VALUE_NAMED_METHOD); + javaFile.addMethod(REMOVE_CONTEXT_VALUE_METHOD); + javaFile.addMethod(REMOVE_CONTEXT_VALUE_NAMED_METHOD); + javaFile.addMethod(GET_PARENT_CONTAINER_METHOD); + javaFile.addMethod(GET_PARENT_CONTAINER_MORE_METHOD); + + // PropertyChangeSupport + addPropertyChangeSupport(root, javaFile); + + // DataBinding + javaFile.addMethod(PROCESS_DATA_BINDING_METHOD); + } + javaFile.addSimpleField(SERIAL_VERSION_UID_FIELD); + javaFile.addSimpleField(ALL_COMPONENTS_CREATED_FIELD); + boolean overrideContextInitialized = false; + FieldDescriptor[] scriptFields = compiler.getScriptFields(); + for (FieldDescriptor f : scriptFields) { + if ("contextInitialized".equals(f.getName())) { + overrideContextInitialized = true; + break; + } + } + if (!overrideContextInitialized) { + javaFile.addSimpleField(CONTEXT_INITIALIZED); + } + javaFile.addSimpleField(createJAXXObjectDescriptorField(compiler, javaFile)); + + if (compiler.getStylesheet() != null) { + boolean needField = true; + if (superclassIsJAXXObject) { + // check alreay exists on parent + ClassDescriptor superclass = root.getObjectClass(); + if (log.isDebugEnabled()) { + log.debug("superclass : " + superclass); + } + JAXXCompiler parentCompiler = compiler.getEngine().getJAXXCompiler(superclass.getName()); + if (parentCompiler != null) { + needField = parentCompiler.getStylesheet() == null; + } else { + try { + + superclass.getDeclaredFieldDescriptor(PREVIOUS_VALUES_FIELD.getName()); + needField = false; + } catch (NoSuchFieldException ex) { + // field not found + } + } + if (needField && log.isDebugEnabled()) { + log.debug("no " + PREVIOUS_VALUES_FIELD.getName() + " field in super class"); + } + } + if (needField) { + javaFile.addSimpleField(PREVIOUS_VALUES_FIELD); + } + } + //TC 20090228 - only generate constructors if not done in scripts + boolean constructorDetected = false; + MethodDescriptor[] methods = compiler.getScriptMethods(); + for (MethodDescriptor m : methods) { + try { + m.getReturnType(); + if (className.equals(m.getName())) { + constructorDetected = true; + break; + } + } catch (Exception e) { + log.warn("could not find return type " + m); + } + } + if (!constructorDetected) { + javaFile.addMethod(createConstructor(compiler, className, superclassIsJAXXObject)); + javaFile.addMethod(createConstructorWithInitialContext(compiler, className, superclassIsJAXXObject)); + } + + javaFile.addMethod(createInitializer(compiler)); + javaFile.addMethod(GET_JAXX_OBJECT_DESCRIPTOR_METHOD); + + javaFile.addBodyCode(compiler.getBodyCode().toString()); + + javaFile.addMethod(createCompleteSetupMethod(compiler, javaFile, compiler.getInitDataBindings())); + + javaFile.addMethod(newMethod(PUBLIC, "void", "applyDataBinding", + compiler.getApplyDataBinding().toString() + JAXXCompiler.getLineSeparator() + "processDataBinding($binding);", + true, + new JavaArgument("String", "$binding"))); + + javaFile.addMethod(newMethod(PUBLIC, "void", "removeDataBinding", + compiler.getRemoveDataBinding().toString(), true, new JavaArgument("String", "$binding"))); + + javaFile.addMethod(createProcessDataBindingMethod(compiler, superclassIsJAXXObject)); + + addEventHandlers(compiler, javaFile); + + } + + + /*---------------------------------------------------------------------------------*/ + /*-- Create fields ----------------------------------------------------------------*/ + /*---------------------------------------------------------------------------------*/ + protected JavaField createJAXXObjectDescriptorField(JAXXCompiler compiler, JavaFile javaFile) { + try { + JAXXObjectDescriptor descriptor = compiler.getJAXXObjectDescriptor(); + String data = Base64Coder.serialize(descriptor, true); + /*ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + ObjectOutputStream out = new ObjectOutputStream(new GZIPOutputStream(buffer)); + out.writeObject(descriptor); + out.close(); + // the use of the weird deprecated constructor is deliberate -- we need to store the data as a String + // in the compiled class file, since byte array initialization is horribly inefficient compared to + // String initialization. So we store the bytes in the String, and we quite explicitly want a 1:1 + // mapping between bytes and chars, with the high byte of the char set to zero. We can then safely + // reconstitute the original byte[] at a later date. This is unquestionably an abuse of the String + // type, but if we could efficiently store a byte[] we wouldn't have to do this. + String data = new String(buffer.toByteArray(), 0);*/ + + int sizeLimit = 65000; // constant strings are limited to 64K, and I'm not brave enough to push right up to the limit + if (data.length() < sizeLimit) { + return newField(PRIVATE | STATIC, "java.lang.String", "$jaxxObjectDescriptor", false, compiler.getJavaCode(data)); + } else { + StringBuffer initializer = new StringBuffer(); + for (int i = 0; i < data.length(); i += sizeLimit) { + String name = "$jaxxObjectDescriptor" + i; + javaFile.addField(new JavaField(PRIVATE | STATIC, "java.lang.String", name, false, + compiler.getJavaCode(data.substring(i, Math.min(i + sizeLimit, data.length()))))); + if (initializer.length() > 0) { + initializer.append(" + "); + } + initializer.append("String.valueOf(").append(name).append(")"); + } + return newField(PRIVATE | STATIC | FINAL, "java.lang.String", "$jaxxObjectDescriptor", false, initializer.toString()); + } + } catch (IOException e) { + throw new RuntimeException("Internal error: can't-happen error", e); + } + } + + /*---------------------------------------------------------------------------------*/ + /*-- Create methods ---------------------------------------------------------------*/ + /*---------------------------------------------------------------------------------*/ + protected void addPropertyChangeSupport(CompiledObject root, JavaFile javaFile) { + ClassDescriptor currentClass = root.getObjectClass(); + MethodDescriptor firePropertyChange = null; + while (firePropertyChange == null && currentClass != null) { + try { + firePropertyChange = currentClass.getDeclaredMethodDescriptor("firePropertyChange", ClassDescriptorLoader.getClassDescriptor(String.class), + ClassDescriptorLoader.getClassDescriptor(Object.class), + ClassDescriptorLoader.getClassDescriptor(Object.class)); + + } catch (NoSuchMethodException e) { + currentClass = currentClass.getSuperclass(); + } + } + + int modifiers = firePropertyChange != null ? firePropertyChange.getModifiers() : 0; + if (isPublic(modifiers)) { + // we have all the support we need + } + if (isProtected(modifiers)) { + // there is property change support but the firePropertyChange method is protected + javaFile.addMethod(FIRE_PROPERTY_CHANGE_METHOD); + } else { + // either no support at all or firePropertyChange isn't accessible + javaFile.addField(PROPERTY_CHANGE_SUPPORT_FIELD); + javaFile.addMethod(GET_PROPERTY_CHANGE_SUPPORT_METHOD); + javaFile.addMethod(ADD_PROPERTY_CHANGE_SUPPORT_METHOD); + javaFile.addMethod(ADD_PROPERTY_CHANGE_SUPPORT_NAMED_METHOD); + javaFile.addMethod(REMOVE_PROPERTY_CHANGE_SUPPORT_METHOD); + javaFile.addMethod(REMOVE_PROPERTY_CHANGE_SUPPORT_NAMED_METHOD); + javaFile.addMethod(FIRE_PROPERTY_CHANGE_NAMED_METHOD); + } + } + + protected void addEventHandlers(JAXXCompiler compiler, JavaFile javaFile) { + for (Map.Entry<String, Map<ClassDescriptor, List<EventHandler>>> e1 : compiler.getEventHandlers().entrySet()) { + // outer loop is iterating over different objects (well, technically, different Java expressions) + for (Map.Entry<ClassDescriptor, List<EventHandler>> e2 : e1.getValue().entrySet()) { + // iterate over different types of listeners for this particular object (MouseListener, ComponentListener, etc.) + for (EventHandler handler : e2.getValue()) { + // iterate over individual event handlers of a single type + String methodName = compiler.getEventHandlerMethodName(handler); + MethodDescriptor listenerMethod = handler.getListenerMethod(); + if (listenerMethod.getParameterTypes().length != 1) { + throw new CompilerException("Expected event handler " + listenerMethod.getName() + " of class " + handler.getListenerClass() + " to have exactly one argument"); + } + javaFile.addMethod(newMethod(PUBLIC, "void", methodName, handler.getJavaCode(), false, + new JavaArgument(JAXXCompiler.getCanonicalName(listenerMethod.getParameterTypes()[0]), "event"))); + } + } + } + } + + protected JavaMethod createConstructor(JAXXCompiler compiler, String className, boolean superclassIsJAXXObject) throws CompilerException { + StringBuffer code = new StringBuffer(); + String constructorParams = compiler.getRootObject().getConstructorParams(); + String eol = JAXXCompiler.getLineSeparator(); + if (constructorParams != null) { + code.append(" super(").append(constructorParams).append(");").append(eol); + } else { + if (superclassIsJAXXObject) { + code.append(" super();").append(eol); + } + } + code.append("$initialize();"); + code.append(eol); + return newMethod(PUBLIC, null, className, code.toString(), false); + } + + protected JavaMethod createConstructorWithInitialContext(JAXXCompiler compiler, String className, boolean superclassIsJAXXObject) throws CompilerException { + StringBuffer code = new StringBuffer(); + String constructorParams = compiler.getRootObject().getConstructorParams(); + String eol = JAXXCompiler.getLineSeparator(); + if (constructorParams != null) { + code.append(" super(").append(constructorParams).append(");").append(eol); + } else { + if (superclassIsJAXXObject) { + code.append(" super(parentContext);").append(eol); + } + } + if (!superclassIsJAXXObject) { + code.append(Util.class.getName() + ".initContext(this, parentContext);"); + code.append(eol); + } + code.append("$initialize();"); + code.append(eol); + return newMethod(PUBLIC, null, className, code.toString(), false, new JavaArgument(JAXXContext.class.getName(), "parentContext")); + } + + public JavaMethod createInitializer(JAXXCompiler compiler) throws CompilerException { + String eol = JAXXCompiler.getLineSeparator(); + StringBuffer code = new StringBuffer(); + CompiledObject root = compiler.getRootObject(); + code.append("if (allComponentsCreated || !contextInitialized) {"); + code.append(eol); + code.append(" return;"); + code.append(eol); + code.append("}"); + code.append(eol); + //TODO-TC20091025 we should remove this if no used anywhere + code.append("$objectMap.put(").append(compiler.getJavaCode(root.getId())).append(", this);"); + code.append(eol); + + Iterator<CompiledObject> i = compiler.getObjectCreationOrder(); + boolean lastWasMethodCall = false; + //TODO-TC20091025 should do init of root first ? +// root.getDecorator().createInitializer(compiler, root, root, code, lastWasMethodCall); + while (i.hasNext()) { + CompiledObject object = i.next(); + if (object == root) { + continue; + } + CompiledObjectDecorator decorator = object.getDecorator(); + lastWasMethodCall = decorator.createInitializer(compiler, root, object, code, lastWasMethodCall); + } + root.getDecorator().createInitializer(compiler, root, root, code, lastWasMethodCall); +// code.append(eol); + if (compiler.getInitializer().length() > 0) { + code.append(compiler.getInitializer()); +// code.append(eol); + } + code.append("$completeSetup();"); + code.append(eol); + return newMethod(PRIVATE, "void", "$initialize", code.toString(), false); + } + + protected JavaMethod createCompleteSetupMethod(JAXXCompiler compiler, JavaFile javaFile, StringBuffer initDataBindings) { + StringBuffer code = new StringBuffer(); + code.append("allComponentsCreated = true;"); + String eol = JAXXCompiler.getLineSeparator(); + code.append(eol); + for (CompiledObject object : compiler.getObjects().values()) { + CompiledObjectDecorator decorator = object.getDecorator(); + code.append(decorator.createCompleteSetupMethod(compiler, object, javaFile, initDataBindings)); + } + code.append("// init data bindings").append(eol); + code.append(initDataBindings); + + if (compiler.getLateInitializer().length() > 0) { + code.append("// late initializer").append(eol); + code.append(compiler.getLateInitializer()).append(eol); + } + //TC-20090313 add an extra method after complete setup + MethodDescriptor method = compiler.getScriptMethod("$afterCompleteSetup"); + if (method != null) { + code.append("$afterCompleteSetup();").append(eol); + } + return newMethod(PRIVATE, "void", "$completeSetup", code.toString(), false); + } + + protected JavaMethod createProcessDataBindingMethod(JAXXCompiler compiler, boolean superclassIsJAXXObject) { + StringBuffer code = new StringBuffer(); + String eol = JAXXCompiler.getLineSeparator(); + //boolean superclassIsJAXXObject = ClassDescriptorLoader.getClassDescriptor(JAXXObject.class).isAssignableFrom(compiler.getRootObject().getObjectClass()); + // the force parameter forces the update to happen even if it is already in activeBindings. This + // is used on superclass invocations b/c by the time the call gets to the superclass, it is already + // marked active and would otherwise be skipped + if (compiler.getProcessDataBinding().length() > 0) { + code.append(" if (!$force && $activeBindings.contains($dest)) { "); + code.append(eol); + code.append(" return;").append(eol); + code.append("}").append(eol); + code.append("$activeBindings.add($dest);").append(eol); + code.append("try {").append(eol); + code.append(compiler.getProcessDataBinding().toString()); + if (superclassIsJAXXObject) { + code.append(" else {").append(eol); + code.append(" super.processDataBinding($dest, true);").append(eol); + code.append(" }").append(eol); + } + code.append("} finally {").append(eol); + code.append(" $activeBindings.remove($dest);").append(eol); + code.append("}").append(eol); + } else if (superclassIsJAXXObject) { + code.append("super.processDataBinding($dest, true);").append(eol); + } + return newMethod(PUBLIC, "void", "processDataBinding", code.toString(), superclassIsJAXXObject, + new JavaArgument("String", "$dest"), new JavaArgument("boolean", "$force")); + } +} Property changes on: branches/jaxx-2.X/jaxx-compiler/src/main/java/jaxx/compiler/finalizers/DefaultFinalizer.java ___________________________________________________________________ Added: svn:keywords + "Author Date Id Revision HeadURL Added: svn:mergeinfo + Deleted: branches/jaxx-2.X/jaxx-compiler/src/main/java/jaxx/compiler/finalizers/Generator.java =================================================================== --- branches/jaxx-2.X/jaxx-compiler/src/main/java/jaxx/compiler/generators/Generator.java 2009-10-21 13:16:51 UTC (rev 1582) +++ branches/jaxx-2.X/jaxx-compiler/src/main/java/jaxx/compiler/finalizers/Generator.java 2009-10-25 19:48:54 UTC (rev 1594) @@ -1,17 +0,0 @@ -package jaxx.compiler.generators; - -import jaxx.compiler.CompiledObject; -import jaxx.compiler.JAXXCompiler; -import jaxx.compiler.JavaFile; - -/** - * TODO javadoc! - * - * @author chemit - */ -public interface Generator { - - void finalizeCompiler(CompiledObject root, JAXXCompiler compiler, JavaFile javaFile, String packageName, String className); - - void prepareJavaFile(CompiledObject root, JAXXCompiler compiler, JavaFile javaFile, String packageName, String className) throws ClassNotFoundException; -} Deleted: branches/jaxx-2.X/jaxx-compiler/src/main/java/jaxx/compiler/finalizers/GeneratorManager.java =================================================================== --- branches/jaxx-2.X/jaxx-compiler/src/main/java/jaxx/compiler/generators/GeneratorManager.java 2009-10-21 13:16:51 UTC (rev 1582) +++ branches/jaxx-2.X/jaxx-compiler/src/main/java/jaxx/compiler/finalizers/GeneratorManager.java 2009-10-25 19:48:54 UTC (rev 1594) @@ -1,42 +0,0 @@ -package jaxx.compiler.generators; - -import java.util.ArrayList; -import java.util.List; -import java.util.ServiceLoader; - -/** - * - * @author chemit - * @since 2.0.0 - */ -public class GeneratorManager { - - protected static List<Generator> generators; - - public static List<Generator> getGenerators() { - if (generators == null) { - loadGenerators(); - } - return generators; - } - - public static void addGenerator(Generator g) { - getGenerators().add(g); - } - - public static void clear() { - if (generators != null) { - generators.clear(); - generators = null; - } - } - - protected static void loadGenerators() { - if (generators == null) { - generators = new ArrayList<Generator>(); - for (Generator generator : ServiceLoader.load(Generator.class)) { - generators.add(generator); - } - } - } -} Deleted: branches/jaxx-2.X/jaxx-compiler/src/main/java/jaxx/compiler/finalizers/JAXXObjectGenerator.java =================================================================== --- branches/jaxx-2.X/jaxx-compiler/src/main/java/jaxx/compiler/generators/JAXXObjectGenerator.java 2009-10-21 13:16:51 UTC (rev 1582) +++ branches/jaxx-2.X/jaxx-compiler/src/main/java/jaxx/compiler/finalizers/JAXXObjectGenerator.java 2009-10-25 19:48:54 UTC (rev 1594) @@ -1,604 +0,0 @@ -package jaxx.compiler.generators; - -import jaxx.compiler.*; -import jaxx.runtime.Base64Coder; -import jaxx.compiler.CompilerException; -import jaxx.compiler.decorators.CompiledObjectDecorator; -import jaxx.compiler.reflect.ClassDescriptor; -import jaxx.compiler.reflect.ClassDescriptorLoader; -import jaxx.compiler.reflect.FieldDescriptor; -import jaxx.compiler.reflect.MethodDescriptor; -import jaxx.compiler.types.TypeManager; -import jaxx.runtime.JAXXObject; -import jaxx.runtime.JAXXObjectDescriptor; -import jaxx.runtime.JAXXContext; -import jaxx.runtime.Util; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import java.io.IOException; -import java.lang.reflect.Modifier; -import static java.lang.reflect.Modifier.FINAL; -import static java.lang.reflect.Modifier.PROTECTED; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -/** - * This class is a refactoring of the {@link jaxx.compiler.JAXXCompiler}. - * <p/> - * We delegate now the generation of a {@link jaxx.runtime.JAXXObject} to this class, the - * {@link jaxx.compiler.JAXXCompiler} now only deals with the compilation of files. - * - * @author chemit - */ -public class JAXXObjectGenerator implements Generator { - - /** log */ - protected static final Log log = LogFactory.getLog(JAXXObjectGenerator.class); - protected static final JavaField ACTIVE_BINDINGS_FIELD = JavaField.newField(PROTECTED, - "java.util.List<Object>", "$activeBindings", "new ArrayList<Object>()"); - protected static final JavaField BINDING_SOURCES_FIELD = JavaField.newField(PROTECTED, - "java.util.Map<String,Object>", "$bindingSources", "new HashMap<String,Object>()"); - protected static final JavaField OBJECT_MAP_FIELD = JavaField.newField(PROTECTED, - "Map<String,Object>", "$objectMap", "new HashMap<String,Object>()"); - protected static final JavaField ALL_COMPONENTS_CREATED_FIELD = JavaField.newField(java.lang.reflect.Modifier.PRIVATE, - "boolean", "allComponentsCreated"); - protected static final JavaField CONTEXT_INITIALIZED = JavaField.newField(java.lang.reflect.Modifier.PRIVATE, - "boolean", "contextInitialized", "true"); - protected static final JavaField PREVIOUS_VALUES_FIELD = JavaField.newField(0, - "java.util.Map", "$previousValues", "new java.util.HashMap()"); - protected static final JavaField DELEGATE_CONTEXT_FIELD = JavaField.newField(PROTECTED, - JAXXContext.class.getName(), "delegateContext"); - protected static final JavaField PROPERTY_CHANGE_SUPPORT_FIELD = JavaField.newField(0, - "java.beans.PropertyChangeSupport", "$propertyChangeSupport"); - protected static final JavaMethod GET_CONTEXT_VALUE_METHOD = JavaMethod.newMethod(java.lang.reflect.Modifier.PUBLIC, "<T> T", "getContextValue", - "return delegateContext.getContextValue(clazz, null);", - new JavaArgument("Class<T>", "clazz")); - protected static final JavaMethod GET_CONTEXT_VALUE_NAMED_METHOD = JavaMethod.newMethod(java.lang.reflect.Modifier.PUBLIC, "<T> T", "getContextValue", - "return delegateContext.getContextValue(clazz, name);", - new JavaArgument("Class<T>", "clazz"), new JavaArgument("String", "name")); - protected static final JavaMethod SET_CONTEXT_VALUE_NAMED_METHOD = JavaMethod.newMethod(java.lang.reflect.Modifier.PUBLIC, "<T> void", "setContextValue", - "delegateContext.setContextValue(o, name);", - new JavaArgument("T", "o"), new JavaArgument("String", "name")); - protected static final JavaMethod SET_CONTEXT_VALUE_METHOD = JavaMethod.newMethod(java.lang.reflect.Modifier.PUBLIC, "<T> void", "setContextValue", - "delegateContext.setContextValue(o, null);", - new JavaArgument("T", "o")); - protected static final JavaMethod REMOVE_CONTEXT_VALUE_NAMED_METHOD = JavaMethod.newMethod(java.lang.reflect.Modifier.PUBLIC, "<T> void", "removeContextValue", - "delegateContext.removeContextValue(clazz, name);", - new JavaArgument("Class<T>", "clazz"), new JavaArgument("String", "name")); - protected static final JavaMethod REMOVE_CONTEXT_VALUE_METHOD = JavaMethod.newMethod(java.lang.reflect.Modifier.PUBLIC, "<T> void", "removeContextValue", - "delegateContext.removeContextValue(clazz, null);", - new JavaArgument("Class<T>", "clazz")); - protected static final JavaMethod GET_PARENT_CONTAINER_MORE_METHOD = JavaMethod.newMethod(java.lang.reflect.Modifier.PUBLIC, "<O extends Container> O", "getParentContainer", - "return delegateContext.getParentContainer(source, clazz);", - new JavaArgument("Object", "source"), new JavaArgument("Class<O>", "clazz")); - protected static final JavaMethod GET_PARENT_CONTAINER_METHOD = JavaMethod.newMethod(java.lang.reflect.Modifier.PUBLIC, "<O extends Container> O", "getParentContainer", - "return delegateContext.getParentContainer(clazz);", - new JavaArgument("Class<O>", "clazz")); - protected static final JavaMethod GET_OBJECT_BY_ID_METHOD = JavaMethod.newMethod(java.lang.reflect.Modifier.PUBLIC, "java.lang.Object", "getObjectById", - "return $objectMap.get(id);", - new JavaArgument("String", "id")); - protected static final JavaMethod GET_JAXX_OBJECT_DESCRIPTOR_METHOD = JavaMethod.newMethod(java.lang.reflect.Modifier.PUBLIC | java.lang.reflect.Modifier.STATIC, "jaxx.runtime.JAXXObjectDescriptor", "$getJAXXObjectDescriptor", - "return jaxx.runtime.Util.decodeCompressedJAXXObjectDescriptor($jaxxObjectDescriptor);"); - protected static final JavaMethod PROCESS_DATA_BINDING_METHOD = JavaMethod.newMethod(java.lang.reflect.Modifier.PUBLIC, "void", "processDataBinding", - "processDataBinding(dest, false);", - new JavaArgument("String", "dest")); - protected static final JavaMethod FIRE_PROPERTY_CHANGE_METHOD = JavaMethod.newMethod(java.lang.reflect.Modifier.PUBLIC, "void", "firePropertyChange", - "super.firePropertyChange(propertyName, oldValue, newValue);", - new JavaArgument("String", "propertyName"), new JavaArgument("Object", "oldValue"), new JavaArgument("Object", "newValue")); - protected static final JavaMethod FIRE_PROPERTY_CHANGE_NAMED_METHOD = JavaMethod.newMethod(java.lang.reflect.Modifier.PUBLIC, "void", "firePropertyChange", - "$getPropertyChangeSupport().firePropertyChange(propertyName, oldValue, newValue);", - new JavaArgument("String", "propertyName"), new JavaArgument("Object", "oldValue"), new JavaArgument("Object", "newValue")); - protected static final JavaMethod GET_PROPERTY_CHANGE_SUPPORT_METHOD = JavaMethod.newMethod(0, "java.beans.PropertyChangeSupport", "$getPropertyChangeSupport", - "if ($propertyChangeSupport == null)\n" + - " $propertyChangeSupport = new PropertyChangeSupport(this);\n" + - "return $propertyChangeSupport;"); - protected static final JavaMethod ADD_PROPERTY_CHANGE_SUPPORT_METHOD = JavaMethod.newMethod(java.lang.reflect.Modifier.PUBLIC, "void", "addPropertyChangeListener", - "$getPropertyChangeSupport().addPropertyChangeListener(listener);", - new JavaArgument("java.beans.PropertyChangeListener", "listener")); - protected static final JavaMethod ADD_PROPERTY_CHANGE_SUPPORT_NAMED_METHOD = JavaMethod.newMethod(java.lang.reflect.Modifier.PUBLIC, "void", "addPropertyChangeListener", - "$getPropertyChangeSupport().addPropertyChangeListener(property, listener);", - new JavaArgument("String", "property"), new JavaArgument("java.beans.PropertyChangeListener", "listener")); - protected static final JavaMethod REMOVE_PROPERTY_CHANGE_SUPPORT_METHOD = JavaMethod.newMethod(java.lang.reflect.Modifier.PUBLIC, "void", "removePropertyChangeListener", - "$getPropertyChangeSupport().removePropertyChangeListener(listener);", - new JavaArgument("java.beans.PropertyChangeListener", "listener")); - protected static final JavaMethod REMOVE_PROPERTY_CHANGE_SUPPORT_NAMED_METHOD = JavaMethod.newMethod(java.lang.reflect.Modifier.PUBLIC, "void", "removePropertyChangeListener", - "$getPropertyChangeSupport().removePropertyChangeListener(property, listener);", - new JavaArgument("String", "property"), new JavaArgument("java.beans.PropertyChangeListener", "listener")); - - @Override - public void finalizeCompiler(CompiledObject root, JAXXCompiler compiler, JavaFile javaFile, String packageName, String className) { - - String fullClassName = packageName != null ? packageName + "." + className : className; - if (root == null) { - throw new CompilerException("root tag must be a class tag"); - } - //Map<String, CompiledObject> objects = compiler.getObjects(); - ClassDescriptor superclass = root.getObjectClass(); - boolean superclassIsJAXXObject = ClassDescriptorLoader.getClassDescriptor(JAXXObject.class).isAssignableFrom(superclass); - javaFile.setModifiers(Modifier.PUBLIC); - javaFile.setClassName(fullClassName); - javaFile.setSuperClass(JAXXCompiler.getCanonicalName(superclass)); - javaFile.setSuperclassIsJAXXObject(superclassIsJAXXObject); - - javaFile.addInterfaces(compiler.getExtraInterfaces()); - javaFile.setAbstractClass(compiler.isAbstractClass()); - javaFile.setGenericType(compiler.getGenericType()); - javaFile.setSuperGenericType(compiler.getSuperGenericType()); - - for (CompiledObject object : compiler.getObjects().values()) { - CompiledObjectDecorator decorator = object.getDecorator(); - decorator.finalizeCompiler(compiler, root, object, javaFile, packageName, className, fullClassName); - - /*if (!object.isOverride() && !(object instanceof ScriptInitializer)) { - String id = object.getId(); - int access = id.startsWith("$") ? Modifier.PRIVATE : Modifier.PROTECTED; - if (object == root) { - javaFile.addField(new JavaField(access, fullClassName, id, "this")); - } else { - //TC -20081017 can have generic on compiled Object - javaFile.addField(JavaField.newField(access, JAXXCompiler.getCanonicalName(object), id), object.isJavaBean()); - } - } - - if (!compiler.inlineCreation(object) && object != root) { - javaFile.addMethod(JavaMethod.newMethod(Modifier.PROTECTED, "void", object.getCreationMethodName(), getCreationCode(compiler, object))); - }*/ - } - - // DataBinding - for (DataBinding dataBinding : compiler.getDataBindings()) { - if (dataBinding.compile(true)) { - compiler.getInitDataBindings().append("applyDataBinding(").append(TypeManager.getJavaCode(dataBinding.getId())).append(");").append(JAXXCompiler.getLineSeparator()); - } - } - - if (superclassIsJAXXObject) { - boolean hasBind = compiler.getApplyDataBinding().length() > 0; - if (hasBind) { - compiler.appendApplyDataBinding(" else {"); - compiler.appendApplyDataBinding(JAXXCompiler.getLineSeparator()); - compiler.appendApplyDataBinding(" "); - } - compiler.appendApplyDataBinding("super.applyDataBinding($binding);"); - compiler.appendApplyDataBinding(JAXXCompiler.getLineSeparator()); - - if (hasBind) { - compiler.appendApplyDataBinding(" return;"); - compiler.appendApplyDataBinding(JAXXCompiler.getLineSeparator()); - compiler.appendApplyDataBinding("}"); - } - - - hasBind = compiler.getRemoveDataBinding().length() > 0; - if (hasBind) { - compiler.appendRemoveDataBinding(" else {"); - compiler.appendRemoveDataBinding(JAXXCompiler.getLineSeparator()); - compiler.appendRemoveDataBinding(" "); - } - compiler.appendRemoveDataBinding("super.removeDataBinding($binding);"); - compiler.appendRemoveDataBinding(JAXXCompiler.getLineSeparator()); - - if (hasBind) { - compiler.appendRemoveDataBinding("}"); - } - } else { - javaFile.addInterface(JAXXCompiler.getCanonicalName(JAXXObject.class)); - } - } - - @Override - public void prepareJavaFile(CompiledObject root, JAXXCompiler compiler, JavaFile javaFile, String packageName, String className) throws ClassNotFoundException { - - String fullClassName = javaFile.getClassName(); - - String jaxxContextImplementorClass = compiler.getConfiguration().getJaxxContextClass().getName(); - boolean superclassIsJAXXObject = javaFile.isSuperclassIsJAXXObject(); - if (!superclassIsJAXXObject) { - // add logger - if (compiler.getConfiguration().isAddLogger()) { - javaFile.addImport(Log.class); - javaFile.addImport(LogFactory.class); - javaFile.addField(JavaField.newField(Modifier.PUBLIC + Modifier.STATIC + FINAL, "Log", "log", "LogFactory.getLog(" + fullClassName + ".class)")); - } - - // JAXXObject - javaFile.addField(OBJECT_MAP_FIELD); - javaFile.addMethod(GET_OBJECT_BY_ID_METHOD); - javaFile.addField(BINDING_SOURCES_FIELD); - javaFile.addField(ACTIVE_BINDINGS_FIELD); - - // JAXXContext - javaFile.addField(JavaField.newField(PROTECTED | FINAL, JAXXContext.class.getName(), "delegateContext", "new " + jaxxContextImplementorClass + "(this);")); - javaFile.addMethod(SET_CONTEXT_VALUE_METHOD); - javaFile.addMethod(SET_CONTEXT_VALUE_NAMED_METHOD); - javaFile.addMethod(GET_CONTEXT_VALUE_METHOD); - javaFile.addMethod(GET_CONTEXT_VALUE_NAMED_METHOD); - javaFile.addMethod(REMOVE_CONTEXT_VALUE_METHOD); - javaFile.addMethod(REMOVE_CONTEXT_VALUE_NAMED_METHOD); - javaFile.addMethod(GET_PARENT_CONTAINER_METHOD); - javaFile.addMethod(GET_PARENT_CONTAINER_MORE_METHOD); - - // PropertyChangeSupport - addPropertyChangeSupport(root, javaFile); - - // DataBinding - javaFile.addMethod(PROCESS_DATA_BINDING_METHOD); - } - - javaFile.addField(ALL_COMPONENTS_CREATED_FIELD); - boolean overrideContextInitialized = false; - FieldDescriptor[] scriptFields = compiler.getScriptFields(); - for (FieldDescriptor f : scriptFields) { - if ("contextInitialized".equals(f.getName())) { - overrideContextInitialized = true; - break; - } - } - if (!overrideContextInitialized) { - javaFile.addField(CONTEXT_INITIALIZED); - } - javaFile.addField(createJAXXObjectDescriptorField(compiler, javaFile)); - - if (compiler.getStylesheet() != null) { - javaFile.addField(PREVIOUS_VALUES_FIELD); - } - /*for (CompiledObject object : compiler.getObjects().values()) { - List<CompiledObject.ChildRef> refList = object.getChilds(); - if (refList==null || refList.isEmpty()) { - continue; - } - for (ChildRef childRef : refList) { - childRef.addToAdditionCode(buffer); - } - }*/ - //TC 20090228 - only generate constructors if not done in scripts - boolean constructorDetected = false; - MethodDescriptor[] methods = compiler.getScriptMethods(); - for (MethodDescriptor m : methods) { - try { - m.getReturnType(); - if (className.equals(m.getName())) { - constructorDetected = true; - break; - } - } catch (Exception e) { - log.warn("could not find return type " + m); - } - } - if (!constructorDetected) { - javaFile.addMethod(createConstructor(compiler, className, superclassIsJAXXObject)); - javaFile.addMethod(createConstructorWithInitialContext(compiler, className, superclassIsJAXXObject)); - } - - javaFile.addMethod(createInitializer(compiler)); - javaFile.addMethod(GET_JAXX_OBJECT_DESCRIPTOR_METHOD); - - javaFile.addBodyCode(compiler.getBodyCode().toString()); - - javaFile.addMethod(createCompleteSetupMethod(compiler, javaFile, compiler.getInitDataBindings())); - - - javaFile.addMethod(JavaMethod.newMethod(Modifier.PUBLIC, "void", "applyDataBinding", - compiler.getApplyDataBinding().toString() + JAXXCompiler.getLineSeparator() + "processDataBinding($binding);", - new JavaArgument("String", "$binding"))); - - javaFile.addMethod(JavaMethod.newMethod(Modifier.PUBLIC, "void", "removeDataBinding", - compiler.getRemoveDataBinding().toString(), new JavaArgument("String", "$binding"))); - - javaFile.addMethod(createProcessDataBindingMethod(compiler, superclassIsJAXXObject)); - - addEventHandlers(compiler, javaFile); - - } - - - /*---------------------------------------------------------------------------------*/ - /*-- Create fields ----------------------------------------------------------------*/ - /*---------------------------------------------------------------------------------*/ - protected JavaField createJAXXObjectDescriptorField(JAXXCompiler compiler, JavaFile javaFile) { - try { - JAXXObjectDescriptor descriptor = compiler.getJAXXObjectDescriptor(); - String data = Base64Coder.serialize(descriptor, true); - /*ByteArrayOutputStream buffer = new ByteArrayOutputStream(); - ObjectOutputStream out = new ObjectOutputStream(new GZIPOutputStream(buffer)); - out.writeObject(descriptor); - out.close(); - // the use of the weird deprecated constructor is deliberate -- we need to store the data as a String - // in the compiled class file, since byte array initialization is horribly inefficient compared to - // String initialization. So we store the bytes in the String, and we quite explicitly want a 1:1 - // mapping between bytes and chars, with the high byte of the char set to zero. We can then safely - // reconstitute the original byte[] at a later date. This is unquestionably an abuse of the String - // type, but if we could efficiently store a byte[] we wouldn't have to do this. - String data = new String(buffer.toByteArray(), 0);*/ - - int sizeLimit = 65000; // constant strings are limited to 64K, and I'm not brave enough to push right up to the limit - if (data.length() < sizeLimit) { - return JavaField.newField(Modifier.PRIVATE | Modifier.STATIC, "java.lang.String", "$jaxxObjectDescriptor", TypeManager.getJavaCode(data)); - } else { - StringBuffer initializer = new StringBuffer(); - for (int i = 0; i < data.length(); i += sizeLimit) { - String name = "$jaxxObjectDescriptor" + i; - javaFile.addField(new JavaField(Modifier.PRIVATE | Modifier.STATIC, "java.lang.String", name, - TypeManager.getJavaCode(data.substring(i, Math.min(i + sizeLimit, data.length()))))); - if (initializer.length() > 0) { - initializer.append(" + "); - } - initializer.append("String.valueOf(").append(name).append(")"); - } - return JavaField.newField(Modifier.PRIVATE | Modifier.STATIC, "java.lang.String", "$jaxxObjectDescriptor", initializer.toString()); - } - } catch (IOException e) { - throw new RuntimeException("Internal error: can't-happen error", e); - } - } - - /*---------------------------------------------------------------------------------*/ - /*-- Create methods ---------------------------------------------------------------*/ - /*---------------------------------------------------------------------------------*/ - protected void addPropertyChangeSupport(CompiledObject root, JavaFile javaFile) { - ClassDescriptor currentClass = root.getObjectClass(); - MethodDescriptor firePropertyChange = null; - while (firePropertyChange == null && currentClass != null) { - try { - firePropertyChange = currentClass.getDeclaredMethodDescriptor("firePropertyChange", ClassDescriptorLoader.getClassDescriptor(String.class), - ClassDescriptorLoader.getClassDescriptor(Object.class), - ClassDescriptorLoader.getClassDescriptor(Object.class)); - - } catch (NoSuchMethodException e) { - currentClass = currentClass.getSuperclass(); - } - } - - int modifiers = firePropertyChange != null ? firePropertyChange.getModifiers() : 0; - if (Modifier.isPublic(modifiers)) { - // we have all the support we need - } - if (Modifier.isProtected(modifiers)) { - // there is property change support but the firePropertyChange method is protected - javaFile.addMethod(FIRE_PROPERTY_CHANGE_METHOD); - } else { - // either no support at all or firePropertyChange isn't accessible - javaFile.addField(PROPERTY_CHANGE_SUPPORT_FIELD); - javaFile.addMethod(GET_PROPERTY_CHANGE_SUPPORT_METHOD); - javaFile.addMethod(ADD_PROPERTY_CHANGE_SUPPORT_METHOD); - javaFile.addMethod(ADD_PROPERTY_CHANGE_SUPPORT_NAMED_METHOD); - javaFile.addMethod(REMOVE_PROPERTY_CHANGE_SUPPORT_METHOD); - javaFile.addMethod(REMOVE_PROPERTY_CHANGE_SUPPORT_NAMED_METHOD); - javaFile.addMethod(FIRE_PROPERTY_CHANGE_NAMED_METHOD); - } - } - - protected void addEventHandlers(JAXXCompiler compiler, JavaFile javaFile) { - for (Map.Entry<String, Map<ClassDescriptor, List<EventHandler>>> e1 : compiler.getEventHandlers().entrySet()) { - // outer loop is iterating over different objects (well, technically, different Java expressions) - for (Map.Entry<ClassDescriptor, List<EventHandler>> e2 : e1.getValue().entrySet()) { - // iterate over different types of listeners for this particular object (MouseListener, ComponentListener, etc.) - for (EventHandler handler : e2.getValue()) { - // iterate over individual event handlers of a single type - String methodName = compiler.getEventHandlerMethodName(handler); - MethodDescriptor listenerMethod = handler.getListenerMethod(); - if (listenerMethod.getParameterTypes().length != 1) { - throw new CompilerException("Expected event handler " + listenerMethod.getName() + " of class " + handler.getListenerClass() + " to have exactly one argument"); - } - javaFile.addMethod(JavaMethod.newMethod(Modifier.PUBLIC, "void", methodName, handler.getJavaCode(), - new JavaArgument(JAXXCompiler.getCanonicalName(listenerMethod.getParameterTypes()[0]), "event"))); - } - } - } - } - - protected JavaMethod createConstructor(JAXXCompiler compiler, String className, boolean superclassIsJAXXObject) throws CompilerException { - StringBuffer code = new StringBuffer(); - String constructorParams = compiler.getRootObject().getConstructorParams(); - if (constructorParams != null) { - code.append(" super(").append(constructorParams).append(");").append(JAXXCompiler.getLineSeparator()); - } else { - if (superclassIsJAXXObject) { - code.append(" super();").append(JAXXCompiler.getLineSeparator()); - } - } - code.append("$initialize();"); - code.append(JAXXCompiler.getLineSeparator()); - return JavaMethod.newMethod(Modifier.PUBLIC, null, className, code.toString()); - } - - protected JavaMethod createConstructorWithInitialContext(JAXXCompiler compiler, String className, boolean superclassIsJAXXObject) throws CompilerException { - StringBuffer code = new StringBuffer(); - String constructorParams = compiler.getRootObject().getConstructorParams(); - if (constructorParams != null) { - code.append(" super(").append(constructorParams).append(");").append(JAXXCompiler.getLineSeparator()); - } else { - if (superclassIsJAXXObject) { - code.append(" super(parentContext);").append(JAXXCompiler.getLineSeparator()); - } - } - if (!superclassIsJAXXObject) { - code.append(Util.class.getName() + ".initContext(this, parentContext);"); - code.append(JAXXCompiler.getLineSeparator()); - -// code.append("if (parentContext instanceof jaxx.runtime.context.JAXXInitialContext) {"); -// code.append(JAXXCompiler.getLineSeparator()); -// code.append(" ((jaxx.runtime.context.JAXXInitialContext)parentContext).to(this);"); -// code.append(JAXXCompiler.getLineSeparator()); -// code.append("} else {"); -// code.append(JAXXCompiler.getLineSeparator()); -// code.append(" setContextValue(parentContext);"); -// code.append(JAXXCompiler.getLineSeparator()); -// code.append("}"); -// code.append(JAXXCompiler.getLineSeparator()); - } - code.append("$initialize();"); - code.append(JAXXCompiler.getLineSeparator()); - return JavaMethod.newMethod(Modifier.PUBLIC, null, className, code.toString(), new JavaArgument(JAXXContext.class.getName(), "parentContext")); - } - - public JavaMethod createInitializer(JAXXCompiler compiler) throws CompilerException { - StringBuffer code = new StringBuffer(); - CompiledObject root = compiler.getRootObject(); - code.append("if (allComponentsCreated || !contextInitialized) {"); - code.append(JAXXCompiler.getLineSeparator()); - code.append(" return;"); - code.append(JAXXCompiler.getLineSeparator()); - code.append("}"); - code.append(JAXXCompiler.getLineSeparator()); - code.append("$objectMap.put(").append(TypeManager.getJavaCode(root.getId())).append(", this);"); - code.append(JAXXCompiler.getLineSeparator()); - - Iterator<CompiledObject> i = compiler.getObjectCreationOrder(); - boolean lastWasMethodCall = false; - while (i.hasNext()) { - CompiledObject object = i.next(); - if (object == root) { - continue; - } - CompiledObjectDecorator decorator = object.getDecorator(); - lastWasMethodCall = decorator.createInitializer(compiler, root, object, code, lastWasMethodCall); - /*if (object != root && !object.isOverride()) { - if (compiler.inlineCreation(object)) { - if (lastWasMethodCall) { - lastWasMethodCall = false; - code.append(JAXXCompiler.getLineSeparator()); - } - code.append(getCreationCode(compiler, object)); - code.append(JAXXCompiler.getLineSeparator()); - } else { - code.append(object.getCreationMethodName()).append("();"); - code.append(JAXXCompiler.getLineSeparator()); - lastWasMethodCall = true; - } - }*/ - } - root.getDecorator().createInitializer(compiler, root, root, code, lastWasMethodCall); - /*String rootCode = root.getInitializationCode(compiler); - if (rootCode != null && rootCode.length() > 0) { - code.append(rootCode); - code.append(JAXXCompiler.getLineSeparator()); - }*/ - code.append(JAXXCompiler.getLineSeparator()); - if (compiler.getInitializer().length() > 0) { - code.append(compiler.getInitializer()); - code.append(JAXXCompiler.getLineSeparator()); - } - code.append("$completeSetup();"); - code.append(JAXXCompiler.getLineSeparator()); - return JavaMethod.newMethod(Modifier.PRIVATE, "void", "$initialize", code.toString()); - } - - protected JavaMethod createCompleteSetupMethod(JAXXCompiler compiler, JavaFile javaFile, StringBuffer initDataBindings) { - StringBuffer code = new StringBuffer(); - code.append("allComponentsCreated = true;"); - code.append(JAXXCompiler.getLineSeparator()); - for (CompiledObject object : compiler.getObjects().values()) { - CompiledObjectDecorator decorator = object.getDecorator(); - code.append(decorator.createCompleteSetupMethod(compiler, object, javaFile, initDataBindings)); - - /*//TC - 20081017 only generate the method if not empty ? - if (object.getId().startsWith("$")) { - code.append(object.getAdditionCode()).append(JAXXCompiler.getLineSeparator()); - } else { - String additionCode = object.getAdditionCode(); - if (additionCode.length() > 0) { - code.append(object.getAdditionMethodName()).append("();").append(JAXXCompiler.getLineSeparator()); - additionCode = "if (!allComponentsCreated) {" + JAXXCompiler.getLineSeparator() + " return;" + JAXXCompiler.getLineSeparator() + "}" + JAXXCompiler.getLineSeparator() + additionCode; - javaFile.addMethod(JavaMethod.newMethod(Modifier.PROTECTED, "void", object.getAdditionMethodName(), additionCode)); - } - }*/ - //code.append(getLineSeparator()); - } - - code.append(initDataBindings); - - if (compiler.getLateInitializer().length() > 0) { - code.append(compiler.getLateInitializer()); - code.append(JAXXCompiler.getLineSeparator()); - } - //TC-20090313 add an extra method after complete setup - MethodDescriptor method = compiler.getScriptMethod("$afterCompleteSetup"); - if (method != null) { - code.append("$afterCompleteSetup();").append(JAXXCompiler.getLineSeparator()); - } - return JavaMethod.newMethod(Modifier.PRIVATE, "void", "$completeSetup", code.toString()); - } - - protected JavaMethod createProcessDataBindingMethod(JAXXCompiler compiler, boolean superclassIsJAXXObject) { - StringBuffer code = new StringBuffer(); - //boolean superclassIsJAXXObject = ClassDescriptorLoader.getClassDescriptor(JAXXObject.class).isAssignableFrom(compiler.getRootObject().getObjectClass()); - // the force parameter forces the update to happen even if it is already in activeBindings. This - // is used on superclass invocations b/c by the time the call gets to the superclass, it is already - // marked active and would otherwise be skipped - if (compiler.getProcessDataBinding().length() > 0) { - code.append(" if (!$force && $activeBindings.contains($dest)) { "); - code.append(JAXXCompiler.getLineSeparator()); - code.append(" return;"); - code.append(JAXXCompiler.getLineSeparator()); - code.append("}"); - code.append(JAXXCompiler.getLineSeparator()); - code.append("$activeBindings.add($dest);"); - code.append(JAXXCompiler.getLineSeparator()); - code.append("try {"); - code.append(JAXXCompiler.getLineSeparator()); - if (compiler.getProcessDataBinding().length() > 0) { - code.append(compiler.getProcessDataBinding().toString()); - //code.append(JAXXCompiler.getLineSeparator()); - } - if (superclassIsJAXXObject) { - code.append(" else {"); - code.append(JAXXCompiler.getLineSeparator()); - code.append(" super.processDataBinding($dest, true);"); - code.append(JAXXCompiler.getLineSeparator()); - code.append(" }"); - code.append(JAXXCompiler.getLineSeparator()); - } - code.append("} finally {"); - code.append(JAXXCompiler.getLineSeparator()); - code.append(" $activeBindings.remove($dest);"); - code.append(JAXXCompiler.getLineSeparator()); - code.append("}"); - code.append(JAXXCompiler.getLineSeparator()); - } else if (superclassIsJAXXObject) { - code.append("super.processDataBinding($dest, true);"); - code.append(JAXXCompiler.getLineSeparator()); - } - return JavaMethod.newMethod(Modifier.PUBLIC, "void", "processDataBinding", code.toString(), - new JavaArgument("String", "$dest"), new JavaArgument("boolean", "$force")); - } - - /*---------------------------------------------------------------------------------*/ - /*-- Create methods code ----------------------------------------------------------*/ - /*---------------------------------------------------------------------------------*/ - - /* protected String getCreationCode(JAXXCompiler compiler, CompiledObject object) throws CompilerException { - if (object instanceof ScriptInitializer) { - return object.getInitializationCode(compiler); - } - CompiledObjectDecorator decorator = object.getDecorator(); - String result = decorator.getCreationCode(compiler, object); - return result;*/ - /*StringBuffer result = new StringBuffer(); - result.append(object.getId()); - result.append(" = "); - if (object.isJavaBean() && object.getJavaBeanInitCode() != null) { - result.append(object.getJavaBeanInitCode()).append(";"); - } else { - String constructorParams = object.getConstructorParams(); - if (constructorParams != null) { - //TC - 20081017 compiledObject can have generics - result.append(" new ").append(JAXXCompiler.getCanonicalName(object)).append("(").append(constructorParams).append(");"); - //result.append("(").append(getCanonicalName(object.getObjectClass())).append(") new ").append(getCanonicalName(object.getObjectClass())).append("(").append(constructorParams).append(");"); - } else { - //TC - 20081017 compiledObject can have generics - result.append("new ").append(JAXXCompiler.getCanonicalName(object)).append("();"); - } - } - result.append(JAXXCompiler.getLineSeparator()); - String initCode = object.getInitializationCode(compiler); - if (initCode != null && initCode.length() > 0) { - result.append(initCode); - } - result.append("$objectMap.put(").append(TypeManager.getJavaCode(object.getId())).append(", ").append(object.getId()).append(");"); - - return result.toString();*/ -// } -} Copied: branches/jaxx-2.X/jaxx-compiler/src/main/java/jaxx/compiler/finalizers/SwingFinalizer.java (from rev 1582, branches/jaxx-2.X/jaxx-compiler/src/main/java/jaxx/compiler/generators/SwingGenerator.java) =================================================================== --- branches/jaxx-2.X/jaxx-compiler/src/main/java/jaxx/compiler/finalizers/SwingFinalizer.java (rev 0) +++ branches/jaxx-2.X/jaxx-compiler/src/main/java/jaxx/compiler/finalizers/SwingFinalizer.java 2009-10-25 19:48:54 UTC (rev 1594) @@ -0,0 +1,33 @@ +package jaxx.compiler.finalizers; + +import jaxx.compiler.java.JavaArgument; +import jaxx.compiler.java.JavaFile; +import jaxx.compiler.java.JavaFileGenerator; +import jaxx.compiler.*; +import jaxx.compiler.reflect.ClassDescriptorLoader; +import jaxx.runtime.swing.Application; + +import java.lang.reflect.Modifier; + +/** @author chemit */ +public class SwingFinalizer implements JAXXCompilerFinalizer { + + @Override + public void finalizeCompiler(CompiledObject root, JAXXCompiler compiler, JavaFile javaFile, String packageName, String className) { + } + + @Override + public void prepareJavaFile(CompiledObject root, JAXXCompiler compiler, JavaFile javaFile, String packageName, String className) throws ClassNotFoundException { + + if (ClassDescriptorLoader.getClassDescriptor(Application.class.getName()).isAssignableFrom(root.getObjectClass()) && !compiler.isMainDeclared()) { + // TODO: check for existing main method first + javaFile.addMethod(JavaFileGenerator.newMethod( + Modifier.PUBLIC | Modifier.STATIC, + "void", + "main", + "SwingUtilities.invokeLater(new Runnable() { public void run() { new " + className + "().setVisible(true); } });", + false, + new JavaArgument("String[]", "arg"))); + } + } +} Property changes on: branches/jaxx-2.X/jaxx-compiler/src/main/java/jaxx/compiler/finalizers/SwingFinalizer.java ___________________________________________________________________ Added: svn:keywords + "Author Date Id Revision HeadURL Added: svn:mergeinfo + Deleted: branches/jaxx-2.X/jaxx-compiler/src/main/java/jaxx/compiler/finalizers/SwingGenerator.java =================================================================== --- branches/jaxx-2.X/jaxx-compiler/src/main/java/jaxx/compiler/generators/SwingGenerator.java 2009-10-21 13:16:51 UTC (rev 1582) +++ branches/jaxx-2.X/jaxx-compiler/src/main/java/jaxx/compiler/finalizers/SwingGenerator.java 2009-10-25 19:48:54 UTC (rev 1594) @@ -1,27 +0,0 @@ -package jaxx.compiler.generators; - -import jaxx.compiler.*; -import jaxx.compiler.reflect.ClassDescriptorLoader; -import jaxx.runtime.swing.Application; - -import java.lang.reflect.Modifier; - -/** @author chemit */ -public class SwingGenerator implements Generator { - - @Override - public void finalizeCompiler(CompiledObject root, JAXXCompiler compiler, JavaFile javaFile, String packageName, String className) { - } - - @Override - public void prepareJavaFile(CompiledObject root, JAXXCompiler compiler, JavaFile javaFile, String packageName, String className) throws ClassNotFoundException { - - //TODO : move this to jaxx-compiler-swing generator - if (ClassDescriptorLoader.getClassDescriptor(Application.class.getName()).isAssignableFrom(root.getObjectClass()) && !compiler.isMainDeclared()) { - // TODO: check for existing main method first - javaFile.addMethod(JavaMethod.newMethod(Modifier.PUBLIC | Modifier.STATIC, "void", "main", - "SwingUtilities.invokeLater(new Runnable() { public void run() { new " + className + "().setVisible(true); } });", - new JavaArgument("String[]", "arg"))); - } - } -} Copied: branches/jaxx-2.X/jaxx-compiler/src/main/java/jaxx/compiler/finalizers/ValidatorFinalizer.java (from rev 1582, branches/jaxx-2.X/jaxx-compiler/src/main/java/jaxx/compiler/generators/ValidatorGenerator.java) =================================================================== --- branches/jaxx-2.X/jaxx-compiler/src/main/java/jaxx/compiler/finalizers/ValidatorFinalizer.java (rev 0) +++ branches/jaxx-2.X/jaxx-compiler/src/main/java/jaxx/compiler/finalizers/ValidatorFinalizer.java 2009-10-25 19:48:54 UTC (rev 1594) @@ -0,0 +1,97 @@ +package jaxx.compiler.finalizers; + +import jaxx.compiler.java.JavaArgument; +import jaxx.compiler.java.JavaField; +import jaxx.compiler.java.JavaFile; +import jaxx.compiler.java.JavaFileGenerator; +import jaxx.compiler.*; +import jaxx.compiler.CompiledObject.ChildRef; +import jaxx.compiler.reflect.ClassDescriptor; +import jaxx.compiler.reflect.ClassDescriptorLoader; +import jaxx.compiler.tags.validator.BeanValidatorHandler; +import jaxx.compiler.tags.validator.BeanValidatorHandler.CompiledBeanValidator; + +import java.util.List; +import jaxx.runtime.SwingUtil; + +/** @author chemit */ +public class ValidatorFinalizer implements JAXXCompilerFinalizer { + + protected static final JavaField VALIDATOR_IDS_FIELD = JavaFileGenerator.newField(java.lang.reflect.Modifier.PROTECTED, + "java.util.List<String>", "validatorIds", true, "new ArrayList<String>()"); + + @Override + 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()) { + continue; + } + for (ChildRef child : childs) { + String javaCode = child.getChildJavaCode(); + // some validators are defined on this object + boolean found = BeanValidatorHandler.isComponentUsedByValidator(compiler, child.getChild().getId()); + if (found) { + // box the child component in a JxLayer + child.setChildJavaCode(SwingUtil.class.getName() + ".boxComponentWithJxLayer(" + javaCode + ")"); + } + } + } + String eol = JAXXCompiler.getLineSeparator(); + // register validator + compiler.appendLateInitializer("// validator setup" + eol); + for (CompiledBeanValidator validator : BeanValidatorHandler.getValidators(compiler)) { + String id = compiler.getJavaCode(validator.getId()); + compiler.appendLateInitializer("validatorIds.add(" + id + ");"); + compiler.appendLateInitializer(eol); + compiler.appendLateInitializer("getValidator(" + id + ").installUIs();"); + compiler.appendLateInitializer(eol); + compiler.appendLateInitializer("getValidator(" + id + ").reloadBean();"); + //compiler.appendLateInitializer("getValidator(" + id + ").validate();"); + compiler.appendLateInitializer(eol); + } + compiler.appendLateInitializer("validatorIds = java.util.Collections.unmodifiableList(validatorIds);"); + compiler.appendLateInitializer(eol); + } + + @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(); + String validatorFQN = validatorClass.getName(); + javaFile.addImport(validatorFQN); + + //TODO use the specific JAXXValidator interface (swing, gwt,...) + Class<?> validatorInterface = jaxx.runtime.JAXXValidator.class; + + if (javaFile.isSuperclassIsJAXXObject()) { + ClassDescriptor superClass = ClassDescriptorLoader.getClassDescriptor(javaFile.getSuperClass()); + boolean parentIsValidator = ClassDescriptorLoader.getClassDescriptor(validatorInterface).isAssignableFrom(superClass); + + if (parentIsValidator) { + // nothing to generate (use the parent directly) + return; + } + } + + // add JAXXValidator interface + javaFile.addInterface(JAXXCompiler.getCanonicalName(validatorInterface)); + + // implements JAXXValidator + javaFile.addField(VALIDATOR_IDS_FIELD); + javaFile.addMethod(JavaFileGenerator.newMethod( + java.lang.reflect.Modifier.PUBLIC, + validatorFQN + "<?>", + "getValidator", + "return (" + validatorFQN + "<?>) (validatorIds.contains(validatorId) ? getObjectById(validatorId) : null);", + true, + new JavaArgument("String", "validatorId"))); + } +} Property changes on: branches/jaxx-2.X/jaxx-compiler/src/main/java/jaxx/compiler/finalizers/ValidatorFinalizer.java ___________________________________________________________________ Added: svn:keywords + "Author Date Id Revision HeadURL Added: svn:mergeinfo + Deleted: branches/jaxx-2.X/jaxx-compiler/src/main/java/jaxx/compiler/finalizers/ValidatorGenerator.java =================================================================== --- branches/jaxx-2.X/jaxx-compiler/src/main/java/jaxx/compiler/generators/ValidatorGenerator.java 2009-10-21 13:16:51 UTC (rev 1582) +++ branches/jaxx-2.X/jaxx-compiler/src/main/java/jaxx/compiler/finalizers/ValidatorGenerator.java 2009-10-25 19:48:54 UTC (rev 1594) @@ -1,88 +0,0 @@ -package jaxx.compiler.generators; - -import jaxx.compiler.*; -import jaxx.compiler.CompiledObject.ChildRef; -import jaxx.compiler.reflect.ClassDescriptor; -import jaxx.compiler.reflect.ClassDescriptorLoader; -import jaxx.compiler.tags.validator.BeanValidatorHandler; -import jaxx.compiler.tags.validator.BeanValidatorHandler.CompiledBeanValidator; -import jaxx.compiler.types.TypeManager; - -import java.util.List; -import jaxx.runtime.SwingUtil; - -/** @author chemit */ -public class ValidatorGenerator implements Generator { - - protected static final JavaField VALIDATOR_IDS_FIELD = JavaField.newField(java.lang.reflect.Modifier.PROTECTED, - "java.util.List<String>", "validatorIds", "new ArrayList<String>()"); - - @Override - 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()) { - continue; - } - for (ChildRef child : childs) { - String javaCode = child.getChildJavaCode(); - // some validators are defined on this object - boolean found = BeanValidatorHandler.isComponentUsedByValidator(compiler, child.getChild().getId()); - if (found) { - // box the child component in a JxLayer - child.setChildJavaCode(SwingUtil.class.getName() + ".boxComponentWithJxLayer(" + javaCode + ")"); - } - } - } - // register validator - for (CompiledBeanValidator validator : BeanValidatorHandler.getValidators(compiler)) { - String id = TypeManager.getJavaCode(validator.getId()); - compiler.appendLateInitializer("validatorIds.add(" + id + ");"); - compiler.appendLateInitializer(JAXXCompiler.getLineSeparator()); - compiler.appendLateInitializer("getValidator(" + id + ").installUIs();"); - compiler.appendLateInitializer(JAXXCompiler.getLineSeparator()); - compiler.appendLateInitializer("getValidator(" + id + ").reloadBean();"); - //compiler.appendLateInitializer("getValidator(" + id + ").validate();"); - compiler.appendLateInitializer(JAXXCompiler.getLineSeparator()); - } - compiler.appendLateInitializer("validatorIds = java.util.Collections.unmodifiableList(validatorIds);"); - compiler.appendLateInitializer(JAXXCompiler.getLineSeparator()); - } - - @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(); - String validatorFQN = validatorClass.getName(); - javaFile.addImport(validatorFQN); - - //TODO use the specific JAXXValidator interface (swing, gwt,...) - Class<?> validatorInterface = jaxx.runtime.JAXXValidator.class; - - if (javaFile.isSuperclassIsJAXXObject()) { - ClassDescriptor superClass = ClassDescriptorLoader.getClassDescriptor(javaFile.getSuperClass()); - boolean parentIsValidator = ClassDescriptorLoader.getClassDescriptor(validatorInterface).isAssignableFrom(superClass); - - if (parentIsValidator) { - // nothing to generate (use the parent directly) - return; - } - } - - // add JAXXValidator interface - javaFile.addInterface(JAXXCompiler.getCanonicalName(validatorInterface)); - - // implements JAXXValidator - javaFile.addField(VALIDATOR_IDS_FIELD); - javaFile.addMethod(JavaMethod.newMethod(java.lang.reflect.Modifier.PUBLIC, validatorFQN + "<?>", "getValidator", - "return (" + validatorFQN + ") (validatorIds.contains(validatorId) ? getObjectById(validatorId) : null);", - new JavaArgument("String", "validatorId"))); - } -}