Author: tchemit Date: 2008-12-18 09:17:52 +0000 (Thu, 18 Dec 2008) New Revision: 1086 Added: lutinjaxx/trunk/jaxx-core/src/test/java/jaxx/junit/JavaMethodTest.java Modified: lutinjaxx/trunk/jaxx-core/changelog.txt lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/compiler/JavaFile.java lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/compiler/JavaMethod.java Log: improve generation of methods Modified: lutinjaxx/trunk/jaxx-core/changelog.txt =================================================================== --- lutinjaxx/trunk/jaxx-core/changelog.txt 2008-12-15 01:29:43 UTC (rev 1085) +++ lutinjaxx/trunk/jaxx-core/changelog.txt 2008-12-18 09:17:52 UTC (rev 1086) @@ -1,4 +1,5 @@ 0.8 ??? 2009???? + * 20081218 [chemit] - improve generation of methods * 20081214 [chemit] - can now in validation, put error with args (all args must be separated by a ##) - improve event naming : replace the $evXXX by doMEthodName__on__field (except with optimize option) - add jaww.runtime.swing.Utils.fillComboBox to fill a combobox model from a collection Modified: lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/compiler/JavaFile.java =================================================================== --- lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/compiler/JavaFile.java 2008-12-15 01:29:43 UTC (rev 1085) +++ lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/compiler/JavaFile.java 2008-12-18 09:17:52 UTC (rev 1086) @@ -4,10 +4,14 @@ */ package jaxx.compiler; +import jaxx.compiler.JavaMethod.MethodOrder; + import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.Arrays; +import java.util.EnumMap; import java.util.List; +import java.util.Map.Entry; /** * A Java source file being generated for output. Once the class is completely initialized, use the @@ -185,42 +189,53 @@ public String getClassBody() { StringBuffer result = new StringBuffer(); + String lineSeparator = JAXXCompiler.getLineSeparator(); if (fields.size() > 0) { java.util.Collections.sort(fields); // sort fields for (JavaField field : fields) { result.append(addIndentation(field.toString(), 4)); - result.append(JAXXCompiler.getLineSeparator()); + result.append(lineSeparator); } - result.append(JAXXCompiler.getLineSeparator()); + result.append(lineSeparator); } if (rawBodyCode.length() > 0) { result.append(addIndentation("/* begin raw body code */\n", 4)); String s = rawBodyCode.toString(); - if (!s.startsWith("\n")) { - result.append('\n'); + if (!s.startsWith(lineSeparator)) { + result.append(lineSeparator); } result.append(addIndentation(s, 4)); - result.append('\n'); + result.append(lineSeparator); result.append(addIndentation("/* end raw body code */", 4)); - result.append("\n"); + result.append(lineSeparator); } for (JavaFile innerClass : innerClasses) { result.append(addIndentation(innerClass.toString(), 4)); - result.append(JAXXCompiler.getLineSeparator()); - result.append(JAXXCompiler.getLineSeparator()); + result.append(lineSeparator).append(lineSeparator); } - java.util.Collections.sort(methods); // sort methods - for (JavaMethod method : methods) { - result.append(addIndentation(method.toString(), 4)); - result.append(JAXXCompiler.getLineSeparator()); - result.append(JAXXCompiler.getLineSeparator()); + /* + java.util.Collections.sort(methods); // sort methods + + for (JavaMethod method : methods) { + result.append(addIndentation(method.toString(), 4)); + result.append(lineSeparator); + result.append(lineSeparator); } + */ + EnumMap<MethodOrder, List<JavaMethod>> map = JavaMethod.getSortedMethods(methods); + for (Entry<MethodOrder, List<JavaMethod>> entry : map.entrySet()) { + List<JavaMethod> list = entry.getValue(); + entry.getKey().generate(result, list, lineSeparator); + list.clear(); + } + map.clear(); + return result.toString(); } Modified: lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/compiler/JavaMethod.java =================================================================== --- lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/compiler/JavaMethod.java 2008-12-15 01:29:43 UTC (rev 1085) +++ lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/compiler/JavaMethod.java 2008-12-18 09:17:52 UTC (rev 1086) @@ -5,7 +5,13 @@ package jaxx.compiler; import java.lang.reflect.Modifier; +import java.util.ArrayList; +import java.util.Arrays; import java.util.Comparator; +import java.util.EnumMap; +import java.util.EnumSet; +import java.util.Iterator; +import java.util.List; /** * Represents a method in a Java source file being generated for output. <code>JavaMethods</code> are created @@ -214,11 +220,210 @@ return COMPARATOR.compare(this, o); } + public enum MethodOrder { + + statics(Modifier.STATIC, "/*---------------------------------------------------------------------------------*/\n" + + "/*-- Statics methods --------------------------------------------------------------*/\n" + + "/*---------------------------------------------------------------------------------*/") { + }, + + constructors(Modifier.PUBLIC, "/*---------------------------------------------------------------------------------*/\n" + + "/*-- Constructors -----------------------------------------------------------------*/\n" + + "/*---------------------------------------------------------------------------------*/") { + public boolean accept(JavaMethod method) { + return method.returnType == null; + } + }, + + JAXXObject(Modifier.PUBLIC, "/*---------------------------------------------------------------------------------*/\n" + + "/*-- JAXXObject implementation ----------------------------------------------------*/\n" + + "/*---------------------------------------------------------------------------------*/") { + private List<String> methods = Arrays.asList("applyDataBinding", "firePropertyChange", "getObjectById", "get$objectMap", "processDataBinding", "removeDataBinding"); + + public boolean accept(JavaMethod method) { + return methods.contains(method.name); + } + }, + + JAXXContext(Modifier.PUBLIC, "/*---------------------------------------------------------------------------------*/\n" + + "/*-- JAXXContext implementation ---------------------------------------------------*/\n" + + "/*---------------------------------------------------------------------------------*/") { + private List<String> methods = Arrays.asList("getContextValue", "getDelegateContext", "getParentContainer", "removeContextValue", "setContextValue"); + public boolean accept(JavaMethod method) { + return methods.contains(method.name); + } + }, + + JAXXValidation(Modifier.PUBLIC, "/*---------------------------------------------------------------------------------*/\n" + + "/*-- JAXXValidation implementation ------------------------------------------------*/\n" + + "/*---------------------------------------------------------------------------------*/") { + private List<String> methods = Arrays.asList("getValidator", "getValidatorIds"); + + public boolean accept(JavaMethod method) { + return methods.contains(method.name); + } + }, + + events(Modifier.PUBLIC, "/*---------------------------------------------------------------------------------*/\n" + + "/*-- Event methods ----------------------------------------------------------------*/\n" + + "/*---------------------------------------------------------------------------------*/") { + public boolean accept(JavaMethod method) { + return (method.name.startsWith("do") && method.name.indexOf("__") > -1); + } + }, + + publicGetters(Modifier.PUBLIC, "/*---------------------------------------------------------------------------------*/\n" + + "/*-- public acessor methods -------------------------------------------------------*/\n" + + "/*---------------------------------------------------------------------------------*/") { + public boolean accept(JavaMethod method) { + return (method.name.startsWith("get") || method.name.startsWith("is")); + } + }, + + publicSetters(Modifier.PUBLIC, "/*---------------------------------------------------------------------------------*/\n" + + "/*-- public mutator methods -------------------------------------------------------*/\n" + + "/*---------------------------------------------------------------------------------*/") { + public boolean accept(JavaMethod method) { + return (method.name.startsWith("set")); + } + }, + + protectedGetters(Modifier.PROTECTED, "/*---------------------------------------------------------------------------------*/\n" + + "/*-- protected acessors methods ---------------------------------------------------*/\n" + + "/*---------------------------------------------------------------------------------*/") { + public boolean accept(JavaMethod method) { + return (method.name.startsWith("get") || method.name.startsWith("is")); + } + }, + + createMethod(Modifier.PROTECTED | Modifier.PRIVATE, "/*---------------------------------------------------------------------------------*/\n" + + "/*-- ui creation methods ----------------------------------------------------------*/\n" + + "/*---------------------------------------------------------------------------------*/") { + public boolean accept(JavaMethod method) { + return method.name.startsWith("create") || method.name.startsWith("add") || + method.name.equals("$completeSetup") || + method.name.equals("$initialize"); + } + }, + + protecteds(Modifier.PROTECTED, "/*---------------------------------------------------------------------------------*/\n" + + "/*-- Other protected methods ------------------------------------------------------*/\n" + + "/*---------------------------------------------------------------------------------*/") { + }, + + packageLocal(0, "/*---------------------------------------------------------------------------------*/\n" + + "/*-- Package methods --------------------------------------------------------------*/\n" + + "/*---------------------------------------------------------------------------------*/") { + @Override + public boolean accept(int mod) { + return !Modifier.isStatic(mod) && !Modifier.isPublic(mod) && !Modifier.isProtected(mod); + }}, + + privates(Modifier.PRIVATE, "/*---------------------------------------------------------------------------------*/\n" + + "/*-- Private methods --------------------------------------------------------------*/\n" + + "/*---------------------------------------------------------------------------------*/") { + }; + + private final String header; + + private int modifier; + + MethodOrder(int modifier, String header) { + this.header = header; + this.modifier = modifier; + } + + public String getHeader() { + return header; + } + + public boolean accept(JavaMethod method) { + return true; + } + + public boolean accept(int mod) { + return (mod & modifier) != 0; + } + + public boolean accept(int mod, JavaMethod method) { + return accept(mod) && accept(method); + } + + public static MethodOrder valueOf(JavaMethod method, int scope) { + for (MethodOrder o : values()) { + if (o.accept(scope, method)) { + return o; + } + } + throw new IllegalArgumentException("could not find a " + MethodOrder.class + " for method " + method); + } + + public void generate(StringBuffer buffer, List<JavaMethod> methods, String lineSeparator) { + if (methods.isEmpty()) { + return; + } + buffer.append(JavaFile.addIndentation(header, 4)); + buffer.append(lineSeparator).append(lineSeparator); + for (JavaMethod method : methods) { + buffer.append(JavaFile.addIndentation(method.toString(), 4)); + buffer.append(lineSeparator).append(lineSeparator); + } + } + } + + public static EnumMap<MethodOrder, List<JavaMethod>> getSortedMethods(List<JavaMethod> methods) { + + EnumMap<MethodOrder, List<JavaMethod>> result = new EnumMap<MethodOrder, List<JavaMethod>>(MethodOrder.class); + for (MethodOrder methodOrder : MethodOrder.values()) { + result.put(methodOrder, new ArrayList<JavaMethod>()); + } + + EnumSet<MethodOrder> allConstants = EnumSet.allOf(MethodOrder.class); + List<JavaMethod> allMethods = new ArrayList<JavaMethod>(methods); + int[] scopes = new int[]{Modifier.STATIC, Modifier.PUBLIC, Modifier.PROTECTED, Modifier.PRIVATE}; + for (int scope : scopes) { + EnumSet<MethodOrder> constants = getMethodOrderScope(allConstants, scope); + + Iterator<JavaMethod> itMethods = allMethods.iterator(); + while (itMethods.hasNext()) { + JavaMethod method = itMethods.next(); + for (MethodOrder constant : constants) { + if (constant.accept(method.getModifiers(), method)) { + result.get(constant).add(method); + itMethods.remove(); + break; + } + } + } + constants.clear(); + } + + if (!allMethods.isEmpty()) { + throw new IllegalArgumentException("could not find a " + MethodOrder.class + " for method " + allMethods); + } + + for (MethodOrder methodOrder : MethodOrder.values()) { + // sort methods + java.util.Collections.sort(result.get(methodOrder)); + } + return result; + } + + public static EnumSet<MethodOrder> getMethodOrderScope(EnumSet<MethodOrder> allConstants, int scope) { + EnumSet<MethodOrder> constants = EnumSet.noneOf(MethodOrder.class); + for (MethodOrder order : allConstants) { + if (order.accept(scope)) { + constants.add(order); + } + } + return constants; + } + public static final Comparator<JavaMethod> COMPARATOR = new Comparator<JavaMethod>() { public int compare(JavaMethod o1, JavaMethod o2) { - int result; + /*int result; if ((result = compareStatic(o1, o2)) != 0) { return result; } @@ -227,7 +432,7 @@ } if ((result = compareVisibility(o1, o2)) != 0) { return result; - } + }*/ return o1.name.compareTo(o2.name); } Added: lutinjaxx/trunk/jaxx-core/src/test/java/jaxx/junit/JavaMethodTest.java =================================================================== --- lutinjaxx/trunk/jaxx-core/src/test/java/jaxx/junit/JavaMethodTest.java (rev 0) +++ lutinjaxx/trunk/jaxx-core/src/test/java/jaxx/junit/JavaMethodTest.java 2008-12-18 09:17:52 UTC (rev 1086) @@ -0,0 +1,50 @@ +package jaxx.junit; + +import jaxx.compiler.JavaMethod; +import jaxx.compiler.JavaMethod.MethodOrder; +import org.junit.Assert; +import org.junit.Test; + +import java.lang.reflect.Modifier; +import java.util.EnumSet; + +/** @author chemit */ +public class JavaMethodTest { + + @Test + public void testGetMethodOrderScope() { + EnumSet<MethodOrder> allConstants = EnumSet.allOf(MethodOrder.class); + + EnumSet<MethodOrder> constants; + + constants = JavaMethod.getMethodOrderScope(allConstants, Modifier.STATIC); + + Assert.assertEquals(1, constants.size()); + Assert.assertTrue(constants.contains(MethodOrder.statics)); + + constants = JavaMethod.getMethodOrderScope(allConstants, Modifier.PUBLIC); + + Assert.assertEquals(7, constants.size()); + Assert.assertTrue(constants.contains(MethodOrder.constructors)); + Assert.assertTrue(constants.contains(MethodOrder.JAXXObject)); + Assert.assertTrue(constants.contains(MethodOrder.JAXXContext)); + Assert.assertTrue(constants.contains(MethodOrder.JAXXValidation)); + Assert.assertTrue(constants.contains(MethodOrder.events)); + Assert.assertTrue(constants.contains(MethodOrder.publicGetters)); + Assert.assertTrue(constants.contains(MethodOrder.publicSetters)); + + constants = JavaMethod.getMethodOrderScope(allConstants, Modifier.PROTECTED); + + Assert.assertEquals(3, constants.size()); + Assert.assertTrue(constants.contains(MethodOrder.protectedGetters)); + Assert.assertTrue(constants.contains(MethodOrder.protecteds)); + Assert.assertTrue(constants.contains(MethodOrder.createMethod)); + + constants = JavaMethod.getMethodOrderScope(allConstants, Modifier.PRIVATE); + Assert.assertEquals(3, constants.size()); + Assert.assertTrue(constants.contains(MethodOrder.createMethod)); + Assert.assertTrue(constants.contains(MethodOrder.packageLocal)); + Assert.assertTrue(constants.contains(MethodOrder.privates)); + + } +}