Author: tchemit Date: 2010-05-20 07:35:13 +0200 (Thu, 20 May 2010) New Revision: 1926 Url: http://nuiton.org/repositories/revision/jaxx/1926 Log: improve override mecanism Modified: trunk/jaxx-compiler/src/main/java/jaxx/compiler/CompiledObject.java trunk/jaxx-compiler/src/main/java/jaxx/compiler/binding/DataBinding.java trunk/jaxx-compiler/src/main/java/jaxx/compiler/binding/DataListener.java trunk/jaxx-compiler/src/main/java/jaxx/compiler/binding/DataSource.java trunk/jaxx-compiler/src/main/java/jaxx/compiler/decorators/DefaultCompiledObjectDecorator.java trunk/jaxx-compiler/src/main/java/jaxx/compiler/tags/DefaultObjectHandler.java Modified: trunk/jaxx-compiler/src/main/java/jaxx/compiler/CompiledObject.java =================================================================== --- trunk/jaxx-compiler/src/main/java/jaxx/compiler/CompiledObject.java 2010-05-18 18:11:11 UTC (rev 1925) +++ trunk/jaxx-compiler/src/main/java/jaxx/compiler/CompiledObject.java 2010-05-20 05:35:13 UTC (rev 1926) @@ -273,6 +273,16 @@ } /** + * {@code true} when overrides an object in the superclass of the class + * being compiled AND type is also override. + * + * @return {@code true} if this object is an override AND override type + */ + public boolean isOverrideType() { + return isOverride() && !getObjectClass().equals(getOverrideType()); + } + + /** * Sets whether this class overrides an identically-named object in the * parent class. * @@ -709,4 +719,8 @@ public int getGenericTypesLength() { return genericTypes == null ? 0 : genericTypes.length; } + + public String getGetterName() { + return "get"+StringUtils.capitalize(id); + } } Modified: trunk/jaxx-compiler/src/main/java/jaxx/compiler/binding/DataBinding.java =================================================================== --- trunk/jaxx-compiler/src/main/java/jaxx/compiler/binding/DataBinding.java 2010-05-18 18:11:11 UTC (rev 1925) +++ trunk/jaxx-compiler/src/main/java/jaxx/compiler/binding/DataBinding.java 2010-05-20 05:35:13 UTC (rev 1926) @@ -217,6 +217,31 @@ processDataBinding = getProcessDataBindingCode(compiler, dataSource, binding); + Set<String> ids = dataSource.getOverrideIds(); + + if (binding && ids != null && !ids.isEmpty()) { + + // there is some overrides, check trackers + DataListener[] listeners = dataSource.getTrackers(); + for (DataListener listener : listeners) { + String code = listener.getAddListenerCode(); + String newCode = replaceOverrides(compiler, ids, code); + if (code.equals(newCode)) { + listener.addListenerCode = newCode; + if (dataSource.showLog()) { + log.info("Replace overrides [" + code + "] --> [" + newCode + "]"); + } + } + code = listener.getRemoveListenerCode(); + newCode = replaceOverrides(compiler, ids, code); + if (code.equals(newCode)) { + listener.removeListenerCode = newCode; + if (dataSource.showLog()) { + log.info("Replace overrides [" + code + "] --> [" + newCode + "]"); + } + } + } + } return binding; } @@ -244,13 +269,17 @@ String objectCode = dataSource.getObjectCode(); + Set<String> overrideIds = dataSource.getOverrideIds(); // no need to test objectCode not null if on root object boolean needTest = objectCode != null && !objectCode.trim().isEmpty() && !compiler.getRootObject().getId().equals(objectCode + " != null"); if (needTest) { + + objectCode = replaceOverrides(compiler, overrideIds, objectCode); + buffer.append("if (").append(objectCode).append(") {").append(eol); } - String assiggment = getAssignment(compiler, dataSource.getOverrideIds()); - buffer.append(JavaFileGenerator.indent(assiggment, needTest ? 4 : 0, false, eol)); + String assignment = getAssignment(compiler, overrideIds); + buffer.append(JavaFileGenerator.indent(assignment, needTest ? 4 : 0, false, eol)); if (needTest) { buffer.append(eol).append("}"); } @@ -260,16 +289,24 @@ protected String getAssignment(JAXXCompiler compiler, Set<String> overrides) { String s = getAssignment(); + s = replaceOverrides(compiler, overrides, s); + + return s; + } + + protected String replaceOverrides(JAXXCompiler compiler, Set<String> overrides, String code) { if (overrides != null && !overrides.isEmpty()) { - String tmp = s; + String tmp = code; for (String override : overrides) { CompiledObject o = compiler.getCompiledObject(override); - tmp = tmp.replaceFirst(override + ".", o.getJavaCode() + "."); + tmp = tmp.replaceAll(override + "\\.", o.getGetterName() + "()."); +// tmp = tmp.replaceFirst(override + ".", o.getJavaCode() + "."); } - log.info("Assignment with overrides (" + s + ") = " + tmp); - s = tmp; + if (dataSource.showLog()) { + log.info("Assignment with overrides [" + code + "] to [" + tmp + "]"); + } + code = tmp; } - - return s; + return code; } } \ No newline at end of file Modified: trunk/jaxx-compiler/src/main/java/jaxx/compiler/binding/DataListener.java =================================================================== --- trunk/jaxx-compiler/src/main/java/jaxx/compiler/binding/DataListener.java 2010-05-18 18:11:11 UTC (rev 1925) +++ trunk/jaxx-compiler/src/main/java/jaxx/compiler/binding/DataListener.java 2010-05-20 05:35:13 UTC (rev 1926) @@ -49,13 +49,16 @@ /** * code of the add listener */ - protected final String addListenerCode; + protected String addListenerCode; /** * code of the remove listener */ - protected final String removeListenerCode; + protected String removeListenerCode; - public DataListener(String symbol, String objectCode, String addListenerCode, String removeListenerCode) { + public DataListener(String symbol, + String objectCode, + String addListenerCode, + String removeListenerCode) { this.symbol = symbol; this.objectCode = objectCode; this.addListenerCode = addListenerCode; Modified: trunk/jaxx-compiler/src/main/java/jaxx/compiler/binding/DataSource.java =================================================================== --- trunk/jaxx-compiler/src/main/java/jaxx/compiler/binding/DataSource.java 2010-05-18 18:11:11 UTC (rev 1925) +++ trunk/jaxx-compiler/src/main/java/jaxx/compiler/binding/DataSource.java 2010-05-20 05:35:13 UTC (rev 1926) @@ -277,7 +277,7 @@ break; case JavaParserTreeConstants.JJTPRIMARYEXPRESSION: type = determineExpressionType(node); - if (showLog()) { + if (log.isDebugEnabled()) { log.debug("result of determineExpressionType for " + node.getText() + " = " + type); } break; @@ -366,8 +366,10 @@ } catch (NoSuchMethodException e) { if (showLog()) { log.info("Could not find method " + methodName + ", code : " + code + " on : " + contextClass); - for (MethodDescriptor descriptor : contextClass.getMethodDescriptors()) { - log.info(" - " + Modifier.toString(descriptor.getModifiers()) + " " + descriptor.getName() + "(...) : " + descriptor.getReturnType()); + if (log.isDebugEnabled()) { + for (MethodDescriptor descriptor : contextClass.getMethodDescriptors()) { + log.debug(" - " + Modifier.toString(descriptor.getModifiers()) + " " + descriptor.getName() + "(...) : " + descriptor.getReturnType()); + } } } // happens for methods defined in the current JAXX file via scripts 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-18 18:11:11 UTC (rev 1925) +++ trunk/jaxx-compiler/src/main/java/jaxx/compiler/decorators/DefaultCompiledObjectDecorator.java 2010-05-20 05:35:13 UTC (rev 1926) @@ -35,7 +35,6 @@ import jaxx.compiler.java.JavaMethod; import jaxx.compiler.script.ScriptInitializer; import jaxx.compiler.types.TypeManager; -import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -84,28 +83,24 @@ log.debug("finalize " + id); } - if (object.isOverride()) { + boolean override = object.isOverride(); - // add a specialized getter, only if type has changed + if (override) { - if (object.getObjectClass().equals(object.getOverrideType())) { + if (object.isOverrideType()) { - // type is the same do nothing + // add a specialized getter, only if type has changed - return; - } + String methodName = object.getGetterName(); - // add a specialized getter + String body = "return (" + fqn + ") super." + methodName + "();"; - String methodName = "get" + StringUtils.capitalize(id); - - String body = "return (" + fqn + ") " + id + ";"; - - if (log.isDebugEnabled()) { - log.debug("Add specialized getter " + methodName + " : " + body); + if (log.isDebugEnabled()) { + log.debug("Add specialized getter " + methodName + " : " + body); + } + JavaMethod getter = JavaFileGenerator.newMethod(Modifier.PUBLIC, fqn, methodName, body, true); + javaFile.addMethod(getter); } - JavaMethod getter = JavaFileGenerator.newMethod(Modifier.PUBLIC, fqn, methodName, body, true); - javaFile.addMethod(getter); } else { int access = id.startsWith("$") ? Modifier.PRIVATE : Modifier.PROTECTED; @@ -113,73 +108,120 @@ JavaField field = JavaFileGenerator.newField(access, className, id, false, "this"); javaFile.addSimpleField(field); } else { - - JavaField field = JavaFileGenerator.newField(access, fqn, id, object.isOverride()); + + JavaField field = JavaFileGenerator.newField(access, fqn, id, override); javaFile.addField(field, object.isJavaBean()); } } - if (!compiler.inlineCreation(object) && !root.equals(object)) { - javaFile.addMethod(JavaFileGenerator.newMethod(Modifier.PROTECTED, "void", object.getCreationMethodName(), getCreationCode(compiler, object), object.isOverride())); + if (compiler.inlineCreation(object) || root.equals(object)) { + + // nothing more to do here + return; } -// if (!object.isOverride() && !(object instanceof ScriptInitializer)) { -// String id = object.getId(); -// int access = id.startsWith("$") ? Modifier.PRIVATE : Modifier.PROTECTED; -// if (object == root) { -// JavaField field = JavaFileGenerator.newField(access, className, id, false, "this"); -// javaFile.addSimpleField(field); -// } else { -// JavaField field = JavaFileGenerator.newField(access, JAXXCompiler.getCanonicalName(object), id, object.isOverride()); -// javaFile.addField(field, object.isJavaBean()); -// } -// } -// -// if (!compiler.inlineCreation(object) && object != root) { -// javaFile.addMethod(JavaFileGenerator.newMethod(Modifier.PROTECTED, "void", object.getCreationMethodName(), getCreationCode(compiler, object), object.isOverride())); -// } + String code = getCreationCode(compiler, object); + + // tchemit 20100519 Do not add the method only if overriden and code is null + + if (code != null) { + + JavaMethod javaMethod = JavaFileGenerator.newMethod( + Modifier.PROTECTED, + "void", + object.getCreationMethodName(), + code, + override + ); + javaFile.addMethod(javaMethod); + } } @Override public String getCreationCode(JAXXCompiler compiler, CompiledObject object) throws CompilerException { if (object instanceof ScriptInitializer) { - return object.getInitializationCode(compiler); + throw new IllegalStateException("A script initializer can not come in getCreationcode method!"); } String eol = JAXXCompiler.getLineSeparator(); + StringBuffer result = new StringBuffer(); - if (compiler.getRootObject() == object || compiler.inlineCreation(object)) { + StringBuilder init = new StringBuilder(); + + if (compiler.getRootObject().equals(object) || compiler.inlineCreation(object)) { result.append("// inline creation of ").append(object.getId()); } - if (object.isOverride() && object.getOverrideType() == object.getObjectClass()) { - //TC-20090309 on utilise le super code quand l'objet est de meme type - result.append("super.").append(object.getCreationMethodName()).append("();"); + + if (object.isJavaBean() && object.getJavaBeanInitCode() != null) { + init.append(object.getJavaBeanInitCode()); + } else if (object.getInitializer() != null) { + init.append(object.getInitializer()); + } + + boolean addToObjectMap = true; + String id = TypeManager.getJavaCode(object.getId()); + String constructorParams = object.getConstructorParams(); + + if (object.isOverride()) { + + if (init.length() == 0 && constructorParams == null) { + + // no init code is given, no need to add to objectMap + addToObjectMap = false; + } + } + + if (addToObjectMap && init.length() == 0) { + + // on special init, use constructor + String canonicalName = JAXXCompiler.getCanonicalName(object); + init.append("new ").append(canonicalName).append("("); + + if (constructorParams != null) { + init.append(constructorParams); + } + init.append(")"); + } + + String superCall = "super." + object.getCreationMethodName() + "();"; + + if (addToObjectMap) { + result.append(eol); + result.append("$objectMap.put("); + result.append(id); + result.append(", "); + result.append(object.getId()).append(" = "); + result.append(init); + result.append(");"); + result.append(eol); } else { - String init = object.getId() + " = "; - if (object.isJavaBean() && object.getJavaBeanInitCode() != null) { - init += object.getJavaBeanInitCode(); - } else if (object.getInitializer() != null) { - init += object.getInitializer(); - } else { - String canonicalName = JAXXCompiler.getCanonicalName(object); - init += "new " + canonicalName + "("; - String constructorParams = object.getConstructorParams(); - if (constructorParams != null) { - init += constructorParams; - } - init += ")"; + if (object.isOverride()) { + + // when override has no special init code, just use the super method + + result.append(superCall); + } - result.append(eol); - result.append("$objectMap.put(").append(TypeManager.getJavaCode(object.getId())).append(", ").append(init).append(");"); } - result.append(eol); + String initCode = object.getInitializationCode(compiler); if (initCode != null && initCode.length() > 0) { - result.append(initCode); + result.append(eol).append(initCode); } // add client properties addClientProperties(object, result, eol); - return result.toString(); + + String code = result.toString(); + + if (!compiler.inlineCreation(object) && + object.isOverride() && + superCall.equals(code.trim())) { + + // special case : when override but do nothing more + // method creation can be skipped + return null; + } + return code; } @Override @@ -220,8 +262,8 @@ if (object instanceof ScriptInitializer) { // initializer has special direct treatment : can not be in a method - // just push code to compiler - code.append(getCreationCode(compiler, object)); + // just push code to compiler + code.append(object.getInitializationCode(compiler)); // nothing to initialize of a script return lastWasMethodCall; Modified: trunk/jaxx-compiler/src/main/java/jaxx/compiler/tags/DefaultObjectHandler.java =================================================================== --- trunk/jaxx-compiler/src/main/java/jaxx/compiler/tags/DefaultObjectHandler.java 2010-05-18 18:11:11 UTC (rev 1925) +++ trunk/jaxx-compiler/src/main/java/jaxx/compiler/tags/DefaultObjectHandler.java 2010-05-20 05:35:13 UTC (rev 1926) @@ -822,7 +822,6 @@ object.appendInitializationCode(setPropertyCode); } compiler.getBindingHelper().registerDataBinding(object.getId() + "." + propertyName, binding, setPropertyCode); -// compiler.getBindingHelper().registerDataBinding(binding, object.getId() + "." + propertyName, setPropertyCode); } catch (UnsupportedAttributeException e) { compiler.reportError("class " + object.getObjectClass().getName() + " does not support attribute '" + propertyName + "'"); }