r1060 - in lutinjaxx/trunk: jaxx-core jaxx-core/src/main/java/jaxx jaxx-core/src/main/java/jaxx/compiler jaxx-core/src/main/java/jaxx/css jaxx-core/src/main/java/jaxx/runtime jaxx-core/src/main/java/jaxx/runtime/swing jaxx-core/src/main/java/jaxx/tags jaxx-core/src/main/java/jaxx/tags/swing jaxx-core/src/test/java/jaxx/runtime maven-jaxx-plugin maven-jaxx-plugin/src/main/java/org/codelutin/jaxx maven-jaxx-plugin/src/test/java/org/codelutin/jaxx maven-jaxx-plugin/src/test/resources/testcases m
Author: tchemit Date: 2008-12-10 09:04:11 +0000 (Wed, 10 Dec 2008) New Revision: 1060 Added: lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/Base64Coder.java lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/MultiJXPathDecorator.java lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/swing/I18nTableCellHeaderRenderer.java lutinjaxx/trunk/jaxx-core/src/test/java/jaxx/runtime/MultiJXPathDecoratorTest.java lutinjaxx/trunk/maven-jaxx-plugin/src/test/java/org/codelutin/jaxx/Bug1750Test.java lutinjaxx/trunk/maven-jaxx-plugin/src/test/resources/testcases/Bug_1750.xml lutinjaxx/trunk/maven-jaxx-plugin/src/test/resources/testcases/bug_1750/ lutinjaxx/trunk/maven-jaxx-plugin/src/test/resources/testcases/bug_1750/ComboBox.jaxx Modified: lutinjaxx/trunk/jaxx-core/changelog.txt lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/compiler/CompiledObject.java lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/compiler/CompilerOptions.java lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/compiler/JAXXCompilerHelper.java lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/compiler/JAXXObjectGenerator.java lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/css/Rule.java lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/css/Stylesheet.java lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/ComponentDescriptor.java lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/JAXXObjectDescriptor.java lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/JXPathDecorator.java lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/Util.java lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/swing/JAXXButtonGroup.java lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/tags/DefaultObjectHandler.java lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/tags/swing/JRadioButtonHandler.java lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/tags/swing/SwingInitializer.java lutinjaxx/trunk/jaxx-core/src/test/java/jaxx/runtime/JXPathDecoratorTest.java lutinjaxx/trunk/maven-jaxx-plugin/changelog.txt lutinjaxx/trunk/maven-jaxx-plugin/src/main/java/org/codelutin/jaxx/JaxxGeneratorMojo.java Log: - improve JAXXButtonGroup (add ActionChangeListener and toolTipText mecanism) - javabBean attribute use to initialize bean - introduce Base64Coder to fix bug 1750 and control serailVersionUI (put them to 1L for the moment) - introduce MultiJXPathDecorator - add a resetAfterCompile parameter toCompilerOption to keep in test used compilers Modified: lutinjaxx/trunk/jaxx-core/changelog.txt =================================================================== --- lutinjaxx/trunk/jaxx-core/changelog.txt 2008-12-10 08:50:08 UTC (rev 1059) +++ lutinjaxx/trunk/jaxx-core/changelog.txt 2008-12-10 09:04:11 UTC (rev 1060) @@ -1,5 +1,10 @@ 0.7 chemit 200812?? - +* 20081210 [chemit] - improve JAXXButtonGroup (add ActionChangeListener and toolTipText mecanism) +* 20081208 [chemit] - javabBean attribute use to initialize bean + - introduce Base64Coder to fix bug 1750 and control serailVersionUI (put them to 1L for the moment) + - introduce MultiJXPathDecorator + - add a resetAfterCompile parameter toCompilerOption to keep in test used compilers + * 20081207 [chemit] use lutinproject 3.1 - can exclude field from validator * 20081202 [chemit] - add strategy for loading ui in NavigationTreeSelectionAdapter Added: lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/Base64Coder.java =================================================================== --- lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/Base64Coder.java (rev 0) +++ lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/Base64Coder.java 2008-12-10 09:04:11 UTC (rev 1060) @@ -0,0 +1,240 @@ +package jaxx; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.util.zip.GZIPInputStream; +import java.util.zip.GZIPOutputStream; + +/** + * A Base64 Encoder/Decoder. + * <p/> + * <p/> + * This class is used to encode and decode data in Base64 format as described in RFC 1521. + * <p/> + * <p/> + * This is "Open Source" software and released under the <a href="http://www.gnu.org/licenses/lgpl.html">GNU/LGPL</a> license.<br> + * It is provided "as is" without warranty of any kind.<br> + * Copyright 2003: Christian d'Heureuse, Inventec Informatik AG, Switzerland.<br> + * Home page: <a href="http://www.source-code.biz">www.source-code.biz</a><br> + * <p/> + * <p/> + * Version history:<br> + * 2003-07-22 Christian d'Heureuse (chdh): Module created.<br> + * 2005-08-11 chdh: Lincense changed from GPL to LGPL.<br> + * 2006-11-21 chdh:<br> + * Method encode(String) renamed to encodeString(String).<br> + * Method decode(String) renamed to decodeString(String).<br> + * New method encode(byte[],int) added.<br> + * New method decode(String) added.<br> + */ + +public class Base64Coder { + + // Mapping table from 6-bit nibbles to Base64 characters. + private static char[] map1 = new char[64]; + + static { + int i = 0; + for (char c = 'A'; c <= 'Z'; c++) { + map1[i++] = c; + } + for (char c = 'a'; c <= 'z'; c++) { + map1[i++] = c; + } + for (char c = '0'; c <= '9'; c++) { + map1[i++] = c; + } + map1[i++] = '+'; + map1[i] = '/'; + } + + // Mapping table from Base64 characters to 6-bit nibbles. + private static byte[] map2 = new byte[128]; + + static { + for (int i = 0; i < map2.length; i++) { + map2[i] = -1; + } + for (int i = 0; i < 64; i++) { + map2[map1[i]] = (byte) i; + } + } + + /** + * Read the object from Base64 string. + * + * @param s the string representation of serialized object. + * @param gzip if gzip stream + * @return the deserialize object + * @throws java.io.IOException if any io pb + * @throws ClassNotFoundException if class not found ? + */ + public static Object deserialize(String s, boolean gzip) throws IOException, + ClassNotFoundException { + byte[] data = Base64Coder.decode(s); + InputStream stream = new ByteArrayInputStream(data); + if (gzip) { + stream = new GZIPInputStream(stream); + } + ObjectInputStream ois = new ObjectInputStream(stream); + Object o = ois.readObject(); + ois.close(); + return o; + } + + /** + * Write the object to a Base64 string. + * + * @param o the object to serialize + * @param gzip if gzip stream + * @return the string representation + * @throws java.io.IOException if any io pb + */ + public static String serialize(Object o, boolean gzip) throws IOException { + ByteArrayOutputStream stream = new ByteArrayOutputStream(); + ObjectOutputStream oos; + if (gzip) { + oos = new ObjectOutputStream(new GZIPOutputStream(stream)); + } else { + oos = new ObjectOutputStream(stream); + } + oos.writeObject(o); + oos.close(); + return new String(Base64Coder.encode(stream.toByteArray())); + } + + /** + * Encodes a string into Base64 format. + * No blanks or line breaks are inserted. + * + * @param s a String to be encoded. + * @return A String with the Base64 encoded data. + */ + public static String encodeString(String s) { + return new String(encode(s.getBytes())); + } + + /** + * Encodes a byte array into Base64 format. + * No blanks or line breaks are inserted. + * + * @param in an array containing the data bytes to be encoded. + * @return A character array with the Base64 encoded data. + */ + public static char[] encode(byte[] in) { + return encode(in, in.length); + } + + /** + * Encodes a byte array into Base64 format. + * No blanks or line breaks are inserted. + * + * @param in an array containing the data bytes to be encoded. + * @param iLen number of bytes to process in <code>in</code>. + * @return A character array with the Base64 encoded data. + */ + public static char[] encode(byte[] in, int iLen) { + int oDataLen = (iLen * 4 + 2) / 3; // output length without padding + int oLen = ((iLen + 2) / 3) * 4; // output length including padding + char[] out = new char[oLen]; + int ip = 0; + int op = 0; + while (ip < iLen) { + int i0 = in[ip++] & 0xff; + int i1 = ip < iLen ? in[ip++] & 0xff : 0; + int i2 = ip < iLen ? in[ip++] & 0xff : 0; + int o0 = i0 >>> 2; + int o1 = ((i0 & 3) << 4) | (i1 >>> 4); + int o2 = ((i1 & 0xf) << 2) | (i2 >>> 6); + int o3 = i2 & 0x3F; + out[op++] = map1[o0]; + out[op++] = map1[o1]; + out[op] = op < oDataLen ? map1[o2] : '='; + op++; + out[op] = op < oDataLen ? map1[o3] : '='; + op++; + } + return out; + } + + /** + * Decodes a string from Base64 format. + * + * @param s a Base64 String to be decoded. + * @return A String containing the decoded data. + * @throws IllegalArgumentException if the input is not valid Base64 encoded data. + */ + public static String decodeString(String s) { + return new String(decode(s)); + } + + /** + * Decodes a byte array from Base64 format. + * + * @param s a Base64 String to be decoded. + * @return An array containing the decoded data bytes. + * @throws IllegalArgumentException if the input is not valid Base64 encoded data. + */ + public static byte[] decode(String s) { + return decode(s.toCharArray()); + } + + /** + * Decodes a byte array from Base64 format. + * No blanks or line breaks are allowed within the Base64 encoded data. + * + * @param in a character array containing the Base64 encoded data. + * @return An array containing the decoded data bytes. + * @throws IllegalArgumentException if the input is not valid Base64 encoded data. + */ + public static byte[] decode(char[] in) { + int iLen = in.length; + if (iLen % 4 != 0) { + throw new IllegalArgumentException("Length of Base64 encoded input string is not a multiple of 4."); + } + while (iLen > 0 && in[iLen - 1] == '=') { + iLen--; + } + int oLen = (iLen * 3) / 4; + byte[] out = new byte[oLen]; + int ip = 0; + int op = 0; + while (ip < iLen) { + int i0 = in[ip++]; + int i1 = in[ip++]; + int i2 = ip < iLen ? in[ip++] : 'A'; + int i3 = ip < iLen ? in[ip++] : 'A'; + if (i0 > 127 || i1 > 127 || i2 > 127 || i3 > 127) { + throw new IllegalArgumentException("Illegal character in Base64 encoded data."); + } + int b0 = map2[i0]; + int b1 = map2[i1]; + int b2 = map2[i2]; + int b3 = map2[i3]; + if (b0 < 0 || b1 < 0 || b2 < 0 || b3 < 0) { + throw new IllegalArgumentException("Illegal character in Base64 encoded data."); + } + int o0 = (b0 << 2) | (b1 >>> 4); + int o1 = ((b1 & 0xf) << 4) | (b2 >>> 2); + int o2 = ((b2 & 3) << 6) | b3; + out[op++] = (byte) o0; + if (op < oLen) { + out[op++] = (byte) o1; + } + if (op < oLen) { + out[op++] = (byte) o2; + } + } + return out; + } + + // Dummy constructor. + private Base64Coder() { + } + +} // end class Base64Coder + Modified: lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/compiler/CompiledObject.java =================================================================== --- lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/compiler/CompiledObject.java 2008-12-10 08:50:08 UTC (rev 1059) +++ lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/compiler/CompiledObject.java 2008-12-10 09:04:11 UTC (rev 1060) @@ -77,6 +77,9 @@ /** a flag to indicate if javaBean full support must be support for this object by root object */ private boolean javaBean; + /** code to initialize the bean (can be null) */ + private String javaBeanInitCode; + /** the type of the override object (can be null if no oveeride) */ private ClassDescriptor overrideType; @@ -561,4 +564,12 @@ public void setOverrideType(ClassDescriptor overrideType) { this.overrideType = overrideType; } + + public String getJavaBeanInitCode() { + return javaBeanInitCode; + } + + public void setJavaBeanInitCode(String javaBeanInitCode) { + this.javaBeanInitCode = javaBeanInitCode; + } } \ No newline at end of file Modified: lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/compiler/CompilerOptions.java =================================================================== --- lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/compiler/CompilerOptions.java 2008-12-10 08:50:08 UTC (rev 1059) +++ lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/compiler/CompilerOptions.java 2008-12-10 09:04:11 UTC (rev 1060) @@ -20,6 +20,9 @@ /** a flag to add or not logger on generated jaxx files */ private boolean addLogger; + /** a flag to not reset compiler after a compile */ + private boolean resetAfterCompile; + /** the name of implementation of {@link jaxx.runtime.JAXXContext} to be used on {@link jaxx.runtime.JAXXObject}. */ protected String jaxxContextImplementorClass; @@ -191,6 +194,14 @@ this.extraImports = extraImports; } + public boolean isResetAfterCompile() { + return resetAfterCompile; + } + + public void setResetAfterCompile(boolean resetAfterCompile) { + this.resetAfterCompile = resetAfterCompile; + } + @Override public String toString() { StringBuilder sb = new StringBuilder(super.toString()); @@ -202,6 +213,7 @@ sb.append("\noptiomize : ").append(getOptimize()); sb.append("\ni18nable : ").append(isI18nable()); sb.append("\naddLogger : ").append(isAddLogger()); + sb.append("\nresetAfterCompile : ").append(isResetAfterCompile()); sb.append("\njaxxContextImplementorClass : ").append(getJaxxContextImplementorClass()); sb.append("\nextraImports : ").append(getExtraImports()); return sb.toString(); Modified: lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/compiler/JAXXCompilerHelper.java =================================================================== --- lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/compiler/JAXXCompilerHelper.java 2008-12-10 08:50:08 UTC (rev 1059) +++ lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/compiler/JAXXCompilerHelper.java 2008-12-10 09:04:11 UTC (rev 1060) @@ -377,7 +377,7 @@ } finally { //TC - 20081018 only reset when no error was detected - if (errorCount == 0) { + if (options.isResetAfterCompile() && errorCount == 0) { reset(); } } Modified: lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/compiler/JAXXObjectGenerator.java =================================================================== --- lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/compiler/JAXXObjectGenerator.java 2008-12-10 08:50:08 UTC (rev 1059) +++ lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/compiler/JAXXObjectGenerator.java 2008-12-10 09:04:11 UTC (rev 1060) @@ -1,5 +1,6 @@ package jaxx.compiler; +import jaxx.Base64Coder; import jaxx.CompilerException; import jaxx.reflect.ClassDescriptor; import jaxx.reflect.ClassDescriptorLoader; @@ -13,19 +14,16 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileWriter; import java.io.IOException; -import java.io.ObjectOutputStream; import java.io.PrintWriter; import java.lang.reflect.Modifier; +import static java.lang.reflect.Modifier.FINAL; import static java.lang.reflect.Modifier.PROTECTED; -import static java.lang.reflect.Modifier.FINAL; import java.util.Iterator; import java.util.List; import java.util.Map; -import java.util.zip.GZIPOutputStream; /** * This class is a refactoring of the {@link jaxx.compiler.JAXXCompiler}. @@ -159,7 +157,7 @@ // JAXXContext - javaFile.addField(newField(PROTECTED| FINAL, "jaxx.runtime.JAXXContext", "delegateContext","new "+ jaxxContextImplementorClass+ "(this);")); + javaFile.addField(newField(PROTECTED | FINAL, "jaxx.runtime.JAXXContext", "delegateContext", "new " + jaxxContextImplementorClass + "(this);")); javaFile.addMethod(SET_CONTEXT_VALUE_METHOD); javaFile.addMethod(SET_CONTEXT_VALUE_NAMED_METHOD); javaFile.addMethod(GET_CONTEXT_VALUE_METHOD); @@ -267,7 +265,8 @@ protected JavaField createJAXXObjectDescriptorField() { try { JAXXObjectDescriptor descriptor = compiler.getJAXXObjectDescriptor(); - ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + String data = Base64Coder.serialize(descriptor, true); + /*ByteArrayOutputStream buffer = new ByteArrayOutputStream(); ObjectOutputStream out = new ObjectOutputStream(new GZIPOutputStream(buffer)); out.writeObject(descriptor); out.close(); @@ -277,7 +276,7 @@ // 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); + 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) { @@ -552,14 +551,18 @@ StringBuffer result = new StringBuffer(); result.append(object.getId()); result.append(" = "); - 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(");"); + if (object.isJavaBean() && object.getJavaBeanInitCode() != null) { + result.append(object.getJavaBeanInitCode()).append(";"); } else { - //TC - 20081017 compiledObject can have generics - result.append("new ").append(JAXXCompiler.getCanonicalName(object)).append("();"); + 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); Modified: lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/css/Rule.java =================================================================== --- lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/css/Rule.java 2008-12-10 08:50:08 UTC (rev 1059) +++ lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/css/Rule.java 2008-12-10 09:04:11 UTC (rev 1060) @@ -18,7 +18,7 @@ private Selector[] selectors; private Map<String, String> properties; - private static final long serialVersionUID = -5314603817367239301L; + private static final long serialVersionUID = 1L; public Rule(Selector[] selectors, Map<String, String> properties) { Modified: lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/css/Stylesheet.java =================================================================== --- lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/css/Stylesheet.java 2008-12-10 08:50:08 UTC (rev 1059) +++ lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/css/Stylesheet.java 2008-12-10 09:04:11 UTC (rev 1060) @@ -32,7 +32,7 @@ public class Stylesheet implements Serializable { private Rule[] rules; - private static final long serialVersionUID = 1135373056555320671L; + private static final long serialVersionUID = 1L; public Stylesheet() { Modified: lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/ComponentDescriptor.java =================================================================== --- lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/ComponentDescriptor.java 2008-12-10 08:50:08 UTC (rev 1059) +++ lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/ComponentDescriptor.java 2008-12-10 09:04:11 UTC (rev 1060) @@ -11,7 +11,7 @@ String javaClassName; String styleClass; ComponentDescriptor parent; - private static final long serialVersionUID = 3001121176691770788L; + private static final long serialVersionUID = 1L; public ComponentDescriptor(String id, String javaClassName, String styleClass, ComponentDescriptor parent) { Modified: lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/JAXXObjectDescriptor.java =================================================================== --- lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/JAXXObjectDescriptor.java 2008-12-10 08:50:08 UTC (rev 1059) +++ lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/JAXXObjectDescriptor.java 2008-12-10 09:04:11 UTC (rev 1060) @@ -11,7 +11,7 @@ public class JAXXObjectDescriptor implements Serializable { private ComponentDescriptor[] descriptors; private Stylesheet stylesheet; - private static final long serialVersionUID = -1706159556633801154L; + private static final long serialVersionUID = 1L; public JAXXObjectDescriptor(ComponentDescriptor[] descriptors, @@ -29,4 +29,14 @@ public Stylesheet getStylesheet() { return stylesheet; } + + @Override + public String toString() { + StringBuilder buffer = new StringBuilder(); + for (ComponentDescriptor descriptor : descriptors) { + buffer.append("\n").append(descriptor); + } + buffer.append("\n").append(stylesheet); + return buffer.toString(); + } } \ No newline at end of file Modified: lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/JXPathDecorator.java =================================================================== --- lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/JXPathDecorator.java 2008-12-10 08:50:08 UTC (rev 1059) +++ lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/JXPathDecorator.java 2008-12-10 09:04:11 UTC (rev 1060) @@ -1,11 +1,17 @@ package jaxx.runtime; +import org.apache.commons.beanutils.MethodUtils; +import org.apache.commons.beanutils.PropertyUtils; import org.apache.commons.jxpath.JXPathContext; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import java.beans.PropertyDescriptor; +import java.io.Serializable; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; import java.util.List; /** @@ -50,23 +56,192 @@ */ public static <O> JXPathDecorator<O> newDecorator(Class<O> internalClass, String expression) throws IllegalArgumentException, NullPointerException { - return new JXPathDecorator<O>(internalClass, expression); + return new JXPathDecorator<O>(internalClass, expression, true); } /** - * expression to format using {@link String#format(String, Object[])}, all variables are compute - * using using the jxpath tokens. + * Sort a list of data based on the first token property of a given context + * in a given decorator. + * + * @param decorator the decorator to use to sort + * @param datas the list of data to sort + * @param pos the index of context to used in decorator to obtain sorted property. */ - protected String expression; + public static void sort(JXPathDecorator decorator, List<?> datas, int pos) { + Collections.sort(datas, decorator.getComparator(pos)); + } - /** list of jxpath tokens to apply on expression */ - protected String[] tokens; + protected static class Context implements Serializable { + /** + * expression to format using {@link String#format(String, Object[])}, all variables are compute + * using using the jxpath tokens. + */ + protected String expression; + /** list of jxpath tokens to apply on expression */ + protected String[] tokens; + + protected transient Comparator comparator; + + private static final long serialVersionUID = 1L; + + public Context(String expression, String[] tokens) { + this.expression = expression; + this.tokens = tokens; + } + + public String getFirstProperty() { + return tokens[0]; + } + + public Comparator getComparator(JXPathDecorator decorator, int pos) { + if (comparator == null) { + + final String property = tokens[pos]; + + Class<?> type = getType(decorator, pos); + + // does not work with javassist, a shame... + //Comparator<?> comparator = new BeanComparator(property); + + if (Number.class.isAssignableFrom(type) || Comparable.class.isAssignableFrom(type)) { + comparator = new Comparator() { + public int compare(Object o1, Object o2) { + Comparable c1 = getValue(o1); + Comparable c2 = getValue(o2); + return c1.compareTo(c2); + } + + public Comparable<Comparable> getValue(Object o) { + try { + Object r = PropertyUtils.getProperty(o, property); + return (Comparable) r; + } catch (Exception e) { + throw new RuntimeException(e); + } + } + }; + } + if (comparator == null) { + throw new IllegalStateException("could not find comparator for type " + type); + } + //todo fixme add a default comparator basedon toString() comparator ? + return comparator; + } + return comparator; + } + + protected Class<?> getType(JXPathDecorator decorator, int pos) { + ensureTokenIndex(decorator, pos); + + String property = getFirstProperty(); + + if (property == null) { + throw new NullPointerException("could not find property in " + this); + } + + for (PropertyDescriptor descriptor : decorator.getDescriptors()) { + if (property.equals(descriptor.getName())) { + Class<?> type = descriptor.getReadMethod().getReturnType(); + if (type.isPrimitive()) { + type = MethodUtils.getPrimitiveWrapper(type); + } + return type; + } + } + throw new IllegalStateException("could not find read method for property " + property); + } + + @Override + public String toString() { + return "<expression:" + expression + ", tokens:" + Arrays.toString(tokens) + ">"; + } + } + + /** the computed context of the decorator */ + protected Context context; + /** nb jxpath tokens to compute */ protected int nbToken; - protected JXPathDecorator(Class<O> internalClass, String expression) throws IllegalArgumentException, NullPointerException { + /** the initial expression used to compute the decorator context. */ + protected String initialExpression; + + /** cache of descriptors of the internal class (used for sorting) */ + protected transient PropertyDescriptor[] descriptors; + + public String toString(Object bean) { + if (bean == null) { + return null; + } + JXPathContext jxcontext = JXPathContext.newContext(bean); + Object[] args = new Object[nbToken]; + for (int i = 0; i < nbToken; i++) { + args[i] = jxcontext.getValue(context.tokens[i]); + } + return String.format(context.expression, args); + } + + public String getProperty(int pos) { + return getTokens()[pos]; + } + + public String getExpression() { + return context.expression; + } + + public String[] getTokens() { + return context.tokens; + } + + public int getNbToken() { + return nbToken; + } + + public String getInitialExpression() { + return initialExpression; + } + + @Override + public String toString() { + return super.toString() + "<" + context + ">"; + } + + public PropertyDescriptor[] getDescriptors() { + if (descriptors == null) { + descriptors = PropertyUtils.getPropertyDescriptors(internalClass); + } + return descriptors; + } + + public void setContext(Context context) { + this.context = context; + this.nbToken = context.tokens.length; + // always reset comparator + //this.context.comparator = null; + if (log.isDebugEnabled()) { + log.debug(context); + } + } + + protected JXPathDecorator(Class<O> internalClass, String expression, boolean creatContext) throws IllegalArgumentException, NullPointerException { super(internalClass); + this.initialExpression = expression; + if (creatContext) { + setContext(createInitialContext(expression)); + if (log.isDebugEnabled()) { + log.debug(expression + " --> " + this.context); + } + } + } + + @SuppressWarnings({"unchecked"}) + protected Comparator<O> getComparator(int pos) { + ensureTokenIndex(this, pos); + return context.getComparator(this, pos); + } + + protected static Context createInitialContext(String expression) { List<String> lTokens = new ArrayList<String>(); StringBuilder buffer = new StringBuilder(); int size = expression.length(); @@ -96,41 +271,12 @@ // suffix after end jxpath (or all expression if no jxpath) buffer.append(expression.substring(end + 1)); } - - this.tokens = lTokens.toArray(new String[lTokens.size()]); - this.nbToken = tokens.length; - this.expression = buffer.toString(); - if (log.isDebugEnabled()) { - log.debug(expression + " --> " + this); - } + return new Context(buffer.toString(), lTokens.toArray(new String[lTokens.size()])); } - public String toString(Object bean) { - if (bean == null) { - return null; + protected static void ensureTokenIndex(JXPathDecorator decorator, int pos) { + if (pos < -1 || pos > decorator.getNbToken()) { + throw new ArrayIndexOutOfBoundsException("token index " + pos + " is out of bound, can be inside [" + 0 + "," + decorator.nbToken + "]"); } - JXPathContext jxcontext = JXPathContext.newContext(bean); - Object[] args = new Object[nbToken]; - for (int i = 0; i < nbToken; i++) { - args[i] = jxcontext.getValue(tokens[i]); - } - return String.format(expression, args); } - - public String getExpression() { - return expression; - } - - public String[] getTokens() { - return tokens; - } - - public int getNbToken() { - return nbToken; - } - - @Override - public String toString() { - return super.toString() + "<expression:" + expression + ", tokens:" + Arrays.toString(tokens) + ">"; - } } Copied: lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/MultiJXPathDecorator.java (from rev 1047, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/JXPathDecorator.java) =================================================================== --- lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/MultiJXPathDecorator.java (rev 0) +++ lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/MultiJXPathDecorator.java 2008-12-10 09:04:11 UTC (rev 1060) @@ -0,0 +1,119 @@ +package jaxx.runtime; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; +import java.util.StringTokenizer; + +/** + * TODO + * + * @author chemit + * @see jaxx.runtime.Decorator + */ +public class MultiJXPathDecorator<O> extends JXPathDecorator<O> { + + /** to use log facility, just put in your code: log.info(\"...\"); */ + private static final Log log = LogFactory.getLog(MultiJXPathDecorator.class); + + private static final long serialVersionUID = 1L; + + public static <O> MultiJXPathDecorator<O> newDecorator(Class<O> internalClass, + String expression, + String separator) + throws IllegalArgumentException, NullPointerException { + + return newDecorator(internalClass, expression, separator, separator); + } + + public static <O> MultiJXPathDecorator<O> newDecorator(Class<O> internalClass, + String expression, + String separator, + String separatorReplacement) + throws IllegalArgumentException, NullPointerException { + + Context[] contexts = createInitialContexts(expression, separator, separatorReplacement); + + return new MultiJXPathDecorator<O>(internalClass, expression, separator, separatorReplacement, contexts); + } + + protected Context[] contexts; + protected String separator; + protected String separatorReplacement; + + + protected MultiJXPathDecorator(Class<O> internalClass, String expression, + String separator, String separatorReplacement, + Context[] contexts) throws IllegalArgumentException, NullPointerException { + super(internalClass, expression, false); + this.separator = separator; + this.separatorReplacement = separatorReplacement; + this.contexts = contexts; + + setContextIndex(0); + + if (log.isDebugEnabled()) { + log.debug(expression + " --> " + this.context); + } + } + + public void setContextIndex(int index) { + ensureContextIndex(this, index); + setContext(contexts[index]); + } + + public int getNbContext() { + return contexts.length; + } + + public String getSeparator() { + return separator; + } + + public String getSeparatorReplacement() { + return separatorReplacement; + } + + @Override + protected Comparator<O> getComparator(int pos) { + ensureContextIndex(this, pos); + return contexts[pos].getComparator(this, 0); + } + + protected static Context[] createInitialContexts(String expression, String separator, String separatorReplacement) { + int sep = expression.indexOf(separator); + if (sep == -1) { + return new Context[]{createInitialContext(expression)}; + } + + List<String> tokens = new ArrayList<String>(); + StringTokenizer stk = new StringTokenizer(expression, separator); + while (stk.hasMoreTokens()) { + tokens.add(stk.nextToken()); + } + + int nbTokens = tokens.size(); + Context[] contexts = new Context[nbTokens]; + for (int i = 0; i < nbTokens; i++) { + StringBuilder buffer = new StringBuilder(expression.length()); + for (int j = 0; j < nbTokens; j++) { + int index = (i + j) % nbTokens; + String str = tokens.get(index); + //todo replace %index with %j + buffer.append(separatorReplacement).append(str); + } + contexts[i] = createInitialContext(buffer.substring(separatorReplacement.length())); + } + return contexts; + } + + protected static void ensureContextIndex(MultiJXPathDecorator decorator, int pos) { + if (pos < -1 || pos > decorator.contexts.length) { + throw new ArrayIndexOutOfBoundsException("context index " + pos + " is out of bound, can be inside [" + 0 + "," + decorator.contexts.length + "]"); + } + } + +} \ No newline at end of file Property changes on: lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/MultiJXPathDecorator.java ___________________________________________________________________ Name: svn:mergeinfo + Modified: lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/Util.java =================================================================== --- lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/Util.java 2008-12-10 08:50:08 UTC (rev 1059) +++ lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/Util.java 2008-12-10 09:04:11 UTC (rev 1060) @@ -1,5 +1,6 @@ package jaxx.runtime; +import jaxx.Base64Coder; import jaxx.runtime.validator.BeanValidator; import jaxx.runtime.validator.ErrorListMouseListener; import jaxx.runtime.validator.ErrorTableMouseListener; @@ -7,6 +8,7 @@ import org.apache.commons.logging.LogFactory; import org.jdesktop.jxlayer.JXLayer; +import javax.swing.DefaultListCellRenderer; import javax.swing.JComponent; import javax.swing.JList; import javax.swing.JTable; @@ -18,9 +20,7 @@ import java.beans.IntrospectionException; import java.beans.Introspector; import java.beans.PropertyDescriptor; -import java.io.ByteArrayInputStream; import java.io.IOException; -import java.io.ObjectInputStream; import java.lang.ref.WeakReference; import java.lang.reflect.InvocationHandler; import java.lang.reflect.InvocationTargetException; @@ -35,7 +35,6 @@ import java.util.ListIterator; import java.util.Map; import java.util.WeakHashMap; -import java.util.zip.GZIPInputStream; public class Util { @@ -66,12 +65,13 @@ */ public static JAXXObjectDescriptor decodeJAXXObjectDescriptor(String descriptor) { try { - byte[] data = new byte[descriptor.length()]; + return (JAXXObjectDescriptor) Base64Coder.deserialize(descriptor, false); + /*byte[] data = new byte[descriptor.length()]; // copy low-order bytes into the array. The high-order bytes should all be zero. System.arraycopy(descriptor.getBytes(), 0, data, 0, data.length); //descriptor.getBytes(0, descriptor.length(), data, 0); ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(data)); - return (JAXXObjectDescriptor) in.readObject(); + return (JAXXObjectDescriptor) in.readObject();*/ } catch (IOException e) { throw new RuntimeException("Internal error: can't-happen error", e); @@ -84,12 +84,14 @@ public static JAXXObjectDescriptor decodeCompressedJAXXObjectDescriptor(String descriptor) { try { - byte[] data = new byte[descriptor.length()]; + return (JAXXObjectDescriptor) Base64Coder.deserialize(descriptor, true); + + /*byte[] data = new byte[descriptor.length()]; // copy low-order bytes into the array. The high-order bytes should all be zero. System.arraycopy(descriptor.getBytes(), 0, data, 0, data.length); //descriptor.getBytes(0, descriptor.length(), data, 0); ObjectInputStream in = new ObjectInputStream(new GZIPInputStream(new ByteArrayInputStream(data))); - return (JAXXObjectDescriptor) in.readObject(); + return (JAXXObjectDescriptor) in.readObject();*/ } catch (IOException e) { throw new RuntimeException("Internal error: can't-happen error", e); @@ -507,4 +509,20 @@ beanValidator.setChanged(newValue); } } + + public static <O> DefaultListCellRenderer newDecoratedListCellRenderer(final Decorator<O> decorator) { + return new DefaultListCellRenderer() { + @Override + public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { + String decorated; + if (value instanceof String) { + decorated = (String) value; + } else { + decorated = decorator.toString(value); + } + return super.getListCellRendererComponent(list, decorated, index, isSelected, cellHasFocus); + } + }; + } + } Added: lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/swing/I18nTableCellHeaderRenderer.java =================================================================== --- lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/swing/I18nTableCellHeaderRenderer.java (rev 0) +++ lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/swing/I18nTableCellHeaderRenderer.java 2008-12-10 09:04:11 UTC (rev 1060) @@ -0,0 +1,38 @@ +package jaxx.runtime.swing; + +import static org.codelutin.i18n.I18n._; + +import javax.swing.JLabel; +import javax.swing.JTable; +import javax.swing.table.TableCellRenderer; +import java.awt.Component; + +/** + * A simple TableCellRenderer using a delegate TableCellRenderer to render everything elese thant the text : + * the text is I18nalize. + * + * @author chemit + */ +public class I18nTableCellHeaderRenderer implements TableCellRenderer { + + /** the libelles to display */ + protected final String[] keys; + + /** the delegate cell renderer */ + protected TableCellRenderer delegate; + + public I18nTableCellHeaderRenderer(TableCellRenderer delegate, String... keys) { + this.delegate = delegate; + this.keys = keys; + } + + public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasfocus, int row, int column) { + if (column > keys.length) { + throw new IndexOutOfBoundsException("colum can not be greater than " + keys.length); + } + JLabel rendererComponent = (JLabel) delegate.getTableCellRendererComponent(table, value, isSelected, hasfocus, row, column); + + rendererComponent.setText(_(keys[column])); + return rendererComponent; + } +} Modified: lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/swing/JAXXButtonGroup.java =================================================================== --- lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/swing/JAXXButtonGroup.java 2008-12-10 08:50:08 UTC (rev 1059) +++ lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/swing/JAXXButtonGroup.java 2008-12-10 09:04:11 UTC (rev 1060) @@ -8,6 +8,7 @@ import javax.swing.ButtonGroup; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; +import javax.swing.event.EventListenerList; import java.beans.PropertyChangeListener; import java.beans.PropertyChangeSupport; import java.util.Enumeration; @@ -15,15 +16,33 @@ public class JAXXButtonGroup extends ButtonGroup { public static final String SELECTED_VALUE_PROPERTY = "selectedValue"; + public static final String BUTTON8GROUP_CLIENT_PROPERTY = "$buttonGroup"; + + public static final String VALUE_CLIENT_PROPERTY = "$value"; + + public static final String SELECTED_TIP_CLIENT_PROPERTY = "$selected.toolTipText"; + + public static final String NOT_SELECTED_TIP_CLIENT_PROPERTY = "$not.selected.toolTipText"; + + protected EventListenerList listenerList = new EventListenerList(); + private PropertyChangeSupport propertyChangeSupport; - private Object selectedValue; - private ChangeListener changeListener = new ChangeListener() { + private transient Object selectedValue; + + protected boolean useToolTipText; + + protected transient ChangeEvent changeEvent = new ChangeEvent(this); + + private transient ChangeListener changeListener = new ChangeListener() { public void stateChanged(ChangeEvent e) { updateSelectedValue(); + if (useToolTipText) { + updateToolTipText(); + } } }; - private static final long serialVersionUID = -2096340516687228691L; + private static final long serialVersionUID = 1L; @Override public void add(AbstractButton button) { @@ -45,7 +64,7 @@ while (e.hasMoreElements()) { AbstractButton button = e.nextElement(); if (button.isSelected()) { - Object selectedValue = button.getClientProperty("$value"); + Object selectedValue = button.getClientProperty(VALUE_CLIENT_PROPERTY ); if (selectedValue != getSelectedValue()) { setSelectedValue(selectedValue); } @@ -53,7 +72,19 @@ } } + public void updateToolTipText() { + Enumeration<AbstractButton> e = getElements(); + while (e.hasMoreElements()) { + AbstractButton button = e.nextElement(); + String key = button.isSelected() ? SELECTED_TIP_CLIENT_PROPERTY : NOT_SELECTED_TIP_CLIENT_PROPERTY; + button.setToolTipText((String) button.getClientProperty(key)); + } + } + public boolean isUseToolTipText() { + return useToolTipText; + } + public Object getSelectedValue() { return selectedValue; } @@ -65,7 +96,32 @@ firePropertyChange(oldValue); } + public void setUseToolTipText(boolean useToolTipText) { + this.useToolTipText = useToolTipText; + } + public void setSelectedButton(Object value) { + setSelectedValue(value); + if (value == null) { + Enumeration<AbstractButton> e = getElements(); + while (e.hasMoreElements()) { + AbstractButton button = e.nextElement(); + setSelected(button.getModel(), false); + } + return; + } + + Enumeration<AbstractButton> e = getElements(); + while (e.hasMoreElements()) { + AbstractButton button = e.nextElement(); + Object selectedValue = button.getClientProperty(VALUE_CLIENT_PROPERTY ); + if (value.equals(selectedValue)) { + button.setSelected(true); + break; + } + } + } + protected PropertyChangeSupport getPropertyChangeSupport() { if (propertyChangeSupport == null) { propertyChangeSupport = new PropertyChangeSupport(this); @@ -99,5 +155,61 @@ getPropertyChangeSupport().firePropertyChange(SELECTED_VALUE_PROPERTY, oldValue, getSelectedValue()); } + fireStateChanged(); } + + /** + * Adds a <code>ChangeListener</code> to the button. + * + * @param l the listener to be added + */ + public void addChangeListener(ChangeListener l) { + listenerList.add(ChangeListener.class, l); + } + + /** + * Removes a ChangeListener from the button. + * + * @param l the listener to be removed + */ + public void removeChangeListener(ChangeListener l) { + listenerList.remove(ChangeListener.class, l); + } + + /** + * Returns an array of all the <code>ChangeListener</code>s added + * to this AbstractButton with addChangeListener(). + * + * @return all of the <code>ChangeListener</code>s added or an empty + * array if no listeners have been added + * @since 1.4 + */ + public ChangeListener[] getChangeListeners() { + return listenerList.getListeners(ChangeListener.class); + } + + /** + * Notifies all listeners that have registered interest for + * notification on this event type. The event instance + * is lazily created. + * + * @see EventListenerList + */ + protected void fireStateChanged() { + // Guaranteed to return a non-null array + Object[] listeners = listenerList.getListenerList(); + // Process the listeners last to first, notifying + // those that are interested in this event + for (int i = listeners.length - 2; i >= 0; i -= 2) { + if (listeners[i] == ChangeListener.class) { + // Lazily create the event: + if (changeEvent == null) { + changeEvent = new ChangeEvent(this); + } + ((ChangeListener) listeners[i + 1]).stateChanged(changeEvent); + } + } + } + + } Modified: lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/tags/DefaultObjectHandler.java =================================================================== --- lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/tags/DefaultObjectHandler.java 2008-12-10 08:50:08 UTC (rev 1059) +++ lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/tags/DefaultObjectHandler.java 2008-12-10 09:04:11 UTC (rev 1060) @@ -663,7 +663,10 @@ continue; } if (name.equals("javaBean")) { - object.setJavaBean(true); + object.setJavaBean(true); + if (!value.isEmpty()) { + object.setJavaBeanInitCode(value); + } return; } if (name.equals("implements")) { Modified: lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/tags/swing/JRadioButtonHandler.java =================================================================== --- lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/tags/swing/JRadioButtonHandler.java 2008-12-10 08:50:08 UTC (rev 1059) +++ lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/tags/swing/JRadioButtonHandler.java 2008-12-10 09:04:11 UTC (rev 1060) @@ -18,8 +18,8 @@ import javax.swing.event.ChangeListener; public class JRadioButtonHandler extends DefaultComponentHandler { - private static final String VALUE_PROPERTY = "value"; - private static final String BUTTON_GROUP_PROPERTY = "buttonGroup"; + private static final String VALUE_PROPERTY = JAXXButtonGroup.VALUE_CLIENT_PROPERTY.substring(1); + private static final String BUTTON_GROUP_PROPERTY = JAXXButtonGroup.BUTTON8GROUP_CLIENT_PROPERTY.substring(1); public JRadioButtonHandler(ClassDescriptor beanClass) { super(beanClass); @@ -69,7 +69,7 @@ } return "{ javax.swing.ButtonGroup $buttonGroup = " + valueCode + "; " + id + ".putClientProperty(\"$buttonGroup\", $buttonGroup); $buttonGroup.add(" + id + "); }\n"; } else if (name.equals(VALUE_PROPERTY)) - return "{ " + id + ".putClientProperty(\"$value\", " + valueCode + "); Object $buttonGroup = " + id + ".getClientProperty(\"$buttonGroup\");" + + return "{ " + id + ".putClientProperty(\""+JAXXButtonGroup.VALUE_CLIENT_PROPERTY+"\", " + valueCode + "); Object $buttonGroup = " + id + ".getClientProperty(\""+JAXXButtonGroup.BUTTON8GROUP_CLIENT_PROPERTY+"\");" + " if ($buttonGroup instanceof jaxx.runtime.swing.JAXXButtonGroup) { ((jaxx.runtime.swing.JAXXButtonGroup) $buttonGroup).updateSelectedValue(); } }\n"; else return super.getSetPropertyCode(id, name, valueCode, compiler); Modified: lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/tags/swing/SwingInitializer.java =================================================================== --- lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/tags/swing/SwingInitializer.java 2008-12-10 08:50:08 UTC (rev 1059) +++ lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/tags/swing/SwingInitializer.java 2008-12-10 09:04:11 UTC (rev 1060) @@ -18,8 +18,8 @@ import jaxx.tags.DefaultObjectHandler; import jaxx.tags.TagManager; import jaxx.tags.validator.BeanValidatorHandler; +import jaxx.tags.validator.ExcludeFieldValidatorHandler; import jaxx.tags.validator.FieldValidatorHandler; -import jaxx.tags.validator.ExcludeFieldValidatorHandler; import jaxx.types.KeyStrokeConverter; import jaxx.types.TypeManager; Modified: lutinjaxx/trunk/jaxx-core/src/test/java/jaxx/runtime/JXPathDecoratorTest.java =================================================================== --- lutinjaxx/trunk/jaxx-core/src/test/java/jaxx/runtime/JXPathDecoratorTest.java 2008-12-10 08:50:08 UTC (rev 1059) +++ lutinjaxx/trunk/jaxx-core/src/test/java/jaxx/runtime/JXPathDecoratorTest.java 2008-12-10 09:04:11 UTC (rev 1060) @@ -36,9 +36,9 @@ public void testNullBean() throws Exception { decorator = JXPathDecorator.newDecorator(Object.class, "hello"); expected = "hello"; - assertEquals(expected, decorator.expression); + assertEquals(expected, decorator.getExpression()); assertEquals(0, decorator.nbToken); - assertEquals(0, decorator.tokens.length); + assertEquals(0, decorator.getTokens().length); result = decorator.toString(null); assertEquals(null, result); @@ -48,43 +48,49 @@ public void testNoJXPath() throws Exception { decorator = JXPathDecorator.newDecorator(Object.class, "hello"); expected = "hello"; - assertEquals(expected, decorator.expression); + assertEquals(expected, decorator.getExpression()); assertEquals(0, decorator.nbToken); - assertEquals(0, decorator.tokens.length); + assertEquals(0, decorator.getTokens().length); result = decorator.toString(this); assertEquals(expected, result); } - @Test public void testDecorator() throws Exception { decorator = JXPathDecorator.newDecorator(JXPathDecorator.class, "${expression}$s - ${nbToken}$d"); - assertEquals("%1$s - %2$d", decorator.expression); + assertEquals("%1$s - %2$d", decorator.getExpression()); assertDecoratorInternal(); decorator = JXPathDecorator.newDecorator(JXPathDecorator.class, "${expression}${nbToken}"); - assertEquals("%1%2", decorator.expression); + assertEquals("%1%2", decorator.getExpression()); assertDecoratorInternal(); decorator = JXPathDecorator.newDecorator(JXPathDecorator.class, "before ${expression}$s - ${nbToken}$d after"); - assertEquals("before %1$s - %2$d after", decorator.expression); + assertEquals("before %1$s - %2$d after", decorator.getExpression()); assertDecoratorInternal(); decorator = JXPathDecorator.newDecorator(JXPathDecorator.class, "before${expression}$s-${nbToken}$dafter"); - assertEquals("before%1$s-%2$dafter", decorator.expression); + assertEquals("before%1$s-%2$dafter", decorator.getExpression()); assertDecoratorInternal(); } - public void assertDecoratorInternal() { - assertEquals(2, decorator.nbToken); - assertEquals(2, decorator.tokens.length); - assertEquals("expression", decorator.tokens[0]); - assertEquals("nbToken", decorator.tokens[1]); - expected = String.format(decorator.expression, decorator.getExpression(), decorator.getNbToken()); + public void assertDecoratorInternal(String... tokens) { + assertTokens(tokens); + expected = String.format(decorator.getExpression(), decorator.getExpression(), decorator.getNbToken()); result = decorator.toString(decorator); assertEquals(expected, result); } + private void assertTokens(String... tokens) { + if (tokens.length == 0) { + tokens = new String[]{"expression", "nbToken"}; + } + assertEquals(2, decorator.nbToken); + assertEquals(2, decorator.getTokens().length); + assertEquals(tokens[0], decorator.getTokens()[0]); + assertEquals(tokens[1], decorator.getTokens()[1]); + } + } Copied: lutinjaxx/trunk/jaxx-core/src/test/java/jaxx/runtime/MultiJXPathDecoratorTest.java (from rev 1047, lutinjaxx/trunk/jaxx-core/src/test/java/jaxx/runtime/JXPathDecoratorTest.java) =================================================================== --- lutinjaxx/trunk/jaxx-core/src/test/java/jaxx/runtime/MultiJXPathDecoratorTest.java (rev 0) +++ lutinjaxx/trunk/jaxx-core/src/test/java/jaxx/runtime/MultiJXPathDecoratorTest.java 2008-12-10 09:04:11 UTC (rev 1060) @@ -0,0 +1,149 @@ +package jaxx.runtime; + +import org.junit.After; +import static org.junit.Assert.assertEquals; +import org.junit.Test; + +/** @author chemit */ +public class MultiJXPathDecoratorTest { + + + protected MultiJXPathDecorator<?> decorator; + protected String expected; + protected String result; + + @After + public void after() { + decorator = null; + } + + @Test(expected = NullPointerException.class) + public void testNullInternalClass() throws Exception { + decorator = MultiJXPathDecorator.newDecorator(null, "hello", "#"); + } + + @Test(expected = IllegalArgumentException.class) + public void testMissingRightBrace() throws Exception { + decorator = MultiJXPathDecorator.newDecorator(Object.class, "${haha", "#"); + } + + @Test(expected = IllegalArgumentException.class) + public void testMissingRightBrace2() throws Exception { + decorator = MultiJXPathDecorator.newDecorator(Object.class, "${haha${hum}", "#"); + } + + @Test + public void testNullBean() throws Exception { + decorator = MultiJXPathDecorator.newDecorator(Object.class, "hello", ""); + expected = "hello"; + assertEquals(expected, decorator.getExpression()); + assertEquals(0, decorator.nbToken); + assertEquals(0, decorator.getTokens().length); + + result = decorator.toString(null); + assertEquals(null, result); + } + + @Test + public void testMultiDecorator() throws Exception { + + decorator = MultiJXPathDecorator.newDecorator(JXPathDecorator.class, "${expression}$s#${nbToken}$d", "#", " - "); + assertEquals("%1$s - %2$d", decorator.getExpression()); + assertDecoratorInternal(); + assertEquals(2, decorator.contexts.length); + decorator.setContextIndex(1); + assertEquals("%1$d - %2$s", decorator.getExpression()); + assertTokens("nbToken", "expression"); + expected = String.format(decorator.getExpression(), decorator.getNbToken(), decorator.getExpression()); + result = decorator.toString(decorator); + assertEquals(expected, result); + + decorator = MultiJXPathDecorator.newDecorator(JXPathDecorator.class, "${expression}$s ## ${nbToken}$d", " ## ", " - "); + assertEquals("%1$s - %2$d", decorator.getExpression()); + assertDecoratorInternal(); + assertEquals(2, decorator.contexts.length); + decorator.setContextIndex(1); + assertEquals("%1$d - %2$s", decorator.getExpression()); + assertTokens("nbToken", "expression"); + expected = String.format(decorator.getExpression(), decorator.getNbToken(), decorator.getExpression()); + result = decorator.toString(decorator); + assertEquals(expected, result); + } + + @Test + public void testMultiDecorator2() throws Exception { + + decorator = MultiJXPathDecorator.newDecorator(JXPathDecorator.class, "${expression}$s#${nbToken}$d#${separator}$s", "#", " - "); + + assertEquals("%1$s - %2$d - %3$s", decorator.getExpression()); + assertTokens("expression", "nbToken", "separator"); + assertEquals(3, decorator.contexts.length); + + expected = String.format(decorator.getExpression(), decorator.getExpression(), decorator.getNbToken(), decorator.getSeparator()); + result = decorator.toString(decorator); + assertEquals(expected, result); + + decorator.setContextIndex(1); + assertEquals("%1$d - %2$s - %3$s", decorator.getExpression()); + assertTokens("nbToken", "separator", "expression"); + expected = String.format(decorator.getExpression(), decorator.getNbToken(), decorator.getSeparator(), decorator.getExpression()); + result = decorator.toString(decorator); + assertEquals(expected, result); + + decorator.setContextIndex(2); + assertEquals("%1$s - %2$s - %3$d", decorator.getExpression()); + assertTokens("separator", "expression", "nbToken"); + + expected = String.format(decorator.getExpression(), decorator.getSeparator(), decorator.getExpression(), decorator.getNbToken()); + result = decorator.toString(decorator); + assertEquals(expected, result); + } + + @Test + public void testMultiDecoratorWithMultiRef() throws Exception { + + decorator = MultiJXPathDecorator.newDecorator(JXPathDecorator.class, "${expression}$s#${nbToken}$d#${separator}$s %3$s", "#", " - "); + + assertEquals("%1$s - %2$d - %3$s %3$s", decorator.getExpression()); + assertTokens("expression", "nbToken", "separator"); + assertEquals(3, decorator.contexts.length); + + expected = String.format(decorator.getExpression(), decorator.getExpression(), decorator.getNbToken(), decorator.getSeparator()); + result = decorator.toString(decorator); + assertEquals(expected, result); + + decorator.setContextIndex(1); + assertEquals("%1$d - %2$s %3$s - %3$s", decorator.getExpression()); + assertTokens("nbToken", "separator", "expression"); + expected = String.format(decorator.getExpression(), decorator.getNbToken(), decorator.getSeparator(), decorator.getExpression()); + result = decorator.toString(decorator); + assertEquals(expected, result); + + decorator.setContextIndex(2); + assertEquals("%1$s %3$s - %2$s - %3$d", decorator.getExpression()); + assertTokens("separator", "expression", "nbToken"); + + expected = String.format(decorator.getExpression(), decorator.getSeparator(), decorator.getExpression(), decorator.getNbToken()); + result = decorator.toString(decorator); + assertEquals(expected, result); + } + + public void assertDecoratorInternal(String... tokens) { + assertTokens(tokens); + expected = String.format(decorator.getExpression(), decorator.getExpression(), decorator.getNbToken()); + result = decorator.toString(decorator); + assertEquals(expected, result); + } + + private void assertTokens(String... tokens) { + if (tokens.length == 0) { + tokens = new String[]{"expression", "nbToken"}; + } + assertEquals(tokens.length, decorator.nbToken); + assertEquals(tokens.length, decorator.getTokens().length); + for (int i = 0; i < tokens.length; i++) { + assertEquals(tokens[i], decorator.getTokens()[i]); + } + } + +} \ No newline at end of file Property changes on: lutinjaxx/trunk/jaxx-core/src/test/java/jaxx/runtime/MultiJXPathDecoratorTest.java ___________________________________________________________________ Name: svn:mergeinfo + Modified: lutinjaxx/trunk/maven-jaxx-plugin/changelog.txt =================================================================== --- lutinjaxx/trunk/maven-jaxx-plugin/changelog.txt 2008-12-10 08:50:08 UTC (rev 1059) +++ lutinjaxx/trunk/maven-jaxx-plugin/changelog.txt 2008-12-10 09:04:11 UTC (rev 1060) @@ -1,5 +1,6 @@ 0.7 chemit 200812?? - * 20081207 [chemit] use lutinproject 3.1 +* 20081208 [chemit] - javabBean attribute use to initialize bean +* 20081207 [chemit] use lutinproject 3.1 0.6 chemit 200811?? * 20081108 [chemit] can add extra imports in JaxxGeneratorMojo (will be added to all generated java files). Modified: lutinjaxx/trunk/maven-jaxx-plugin/src/main/java/org/codelutin/jaxx/JaxxGeneratorMojo.java =================================================================== --- lutinjaxx/trunk/maven-jaxx-plugin/src/main/java/org/codelutin/jaxx/JaxxGeneratorMojo.java 2008-12-10 08:50:08 UTC (rev 1059) +++ lutinjaxx/trunk/maven-jaxx-plugin/src/main/java/org/codelutin/jaxx/JaxxGeneratorMojo.java 2008-12-10 09:04:11 UTC (rev 1060) @@ -152,6 +152,14 @@ * @parameter expression="${jaxx.addLogger}" default-value="true" */ protected boolean addLogger; + /** + * flag to keep compilers after the generate operation (usefull for tests. + * <p/> + * By default, always reset. + * + * @parameter expression="${jaxx.resetAfterCompile}" default-value="true" + */ + protected boolean resetAfterCompile; /** * the name of implementation of {@link jaxx.runtime.JAXXContext} @@ -284,6 +292,7 @@ result.setVerbose(verbose); result.setI18nable(i18nable); result.setAddLogger(addLogger); + result.setResetAfterCompile(resetAfterCompile); result.setJaxxContextImplementorClass(jaxxContextImplementorClass); result.setExtraImports(extraImports); return result; Copied: lutinjaxx/trunk/maven-jaxx-plugin/src/test/java/org/codelutin/jaxx/Bug1750Test.java (from rev 1003, lutinjaxx/trunk/maven-jaxx-plugin/src/test/java/org/codelutin/jaxx/Bug1722Test.java) =================================================================== --- lutinjaxx/trunk/maven-jaxx-plugin/src/test/java/org/codelutin/jaxx/Bug1750Test.java (rev 0) +++ lutinjaxx/trunk/maven-jaxx-plugin/src/test/java/org/codelutin/jaxx/Bug1750Test.java 2008-12-10 09:04:11 UTC (rev 1060) @@ -0,0 +1,44 @@ +package org.codelutin.jaxx; + +import jaxx.Base64Coder; +import jaxx.compiler.JAXXCompiler; +import jaxx.compiler.JAXXCompilerHelper; +import jaxx.runtime.JAXXObjectDescriptor; +import jaxx.runtime.Util; + +/** @author chemit */ +public class Bug1750Test extends JaxxBaseTest { + + public void testBug_1750() throws Exception { + mojo.execute(); + assertEquals(1, mojo.getFiles().length); + + JAXXCompiler compiler = JAXXCompilerHelper.getJAXXCompiler("testcases.bug_1750.ComboBox"); + assertNotNull(compiler); + + JAXXObjectDescriptor descriptor = compiler.getJAXXObjectDescriptor(); + assertNotNull(descriptor); + + String data = Base64Coder.serialize(descriptor, false); + + JAXXObjectDescriptor descriptor2 = (JAXXObjectDescriptor) Base64Coder.deserialize(data, false); + assertNotNull(descriptor2); + assertEquals(descriptor.toString(), descriptor2.toString()); + + descriptor2 = Util.decodeJAXXObjectDescriptor(data); + assertNotNull(descriptor2); + assertEquals(descriptor.toString(), descriptor2.toString()); + + data = Base64Coder.serialize(descriptor, true); + + descriptor2 = (JAXXObjectDescriptor) Base64Coder.deserialize(data, true); + assertNotNull(descriptor2); + assertEquals(descriptor.toString(), descriptor2.toString()); + + descriptor2 = Util.decodeCompressedJAXXObjectDescriptor(data); + assertNotNull(descriptor2); + assertEquals(descriptor.toString(), descriptor2.toString()); + + } + +} \ No newline at end of file Property changes on: lutinjaxx/trunk/maven-jaxx-plugin/src/test/java/org/codelutin/jaxx/Bug1750Test.java ___________________________________________________________________ Name: svn:mergeinfo + Copied: lutinjaxx/trunk/maven-jaxx-plugin/src/test/resources/testcases/Bug_1750.xml (from rev 1003, lutinjaxx/trunk/maven-jaxx-plugin/src/test/resources/testcases/Bug_1722.xml) =================================================================== --- lutinjaxx/trunk/maven-jaxx-plugin/src/test/resources/testcases/Bug_1750.xml (rev 0) +++ lutinjaxx/trunk/maven-jaxx-plugin/src/test/resources/testcases/Bug_1750.xml 2008-12-10 09:04:11 UTC (rev 1060) @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + <build> + <plugins> + <plugin> + <groupId>org.codelutin</groupId> + <artifactId>maven-jaxx-plugin</artifactId> + <configuration> + <src>${basedir}/src/test/resources</src> + <outJava>${basedir}/target/it-generated-source/java</outJava> + <outResource>${basedir}/target/it-generated-source/resources</outResource> + <force>true</force> + <verbose>true</verbose> + <resetAfterCompile>false</resetAfterCompile> + <includes> + <value>**/bug_1750/*.jaxx</value> + </includes> + </configuration> + </plugin> + </plugins> + </build> +</project> \ No newline at end of file Property changes on: lutinjaxx/trunk/maven-jaxx-plugin/src/test/resources/testcases/Bug_1750.xml ___________________________________________________________________ Name: svn:mergeinfo + Added: lutinjaxx/trunk/maven-jaxx-plugin/src/test/resources/testcases/bug_1750/ComboBox.jaxx =================================================================== --- lutinjaxx/trunk/maven-jaxx-plugin/src/test/resources/testcases/bug_1750/ComboBox.jaxx (rev 0) +++ lutinjaxx/trunk/maven-jaxx-plugin/src/test/resources/testcases/bug_1750/ComboBox.jaxx 2008-12-10 09:04:11 UTC (rev 1060) @@ -0,0 +1,18 @@ +<Table> + + <!-- selectedItem state --> + <Object id='selectedItem' javaBean=''/> + + <!-- check state --> + <Boolean id='check' constructorParams='false' javaBean=''/> + + <row> + <cell> + <JComboBox id='combobox' selectedItem='{getSelectedItem()}' + onItemStateChanged='setSelectedItem(combobox.getSelectedItem())'/> + </cell> + <cell> + <JCheckBox id='checkbox' selected='{isCheck()}' onActionPerformed='setCheck(checkbox.isSelected())'/> + </cell> + </row> +</Table>
participants (1)
-
tchemit@users.labs.libre-entreprise.org