r2064 - in trunk/jaxx-runtime/src: main/java/jaxx/runtime/decorator test/java/jaxx/runtime/decorator
Author: tchemit Date: 2010-09-06 14:55:58 +0200 (Mon, 06 Sep 2010) New Revision: 2064 Url: http://nuiton.org/repositories/revision/jaxx/2064 Log: Anomalie #853: when using MultiJxPathDecorator, can not use extra token formatter in expression Evolution #850: Can sort in reverse order in DecoratorUtils + reformat code, fix test Modified: trunk/jaxx-runtime/src/main/java/jaxx/runtime/decorator/DecoratorUtils.java trunk/jaxx-runtime/src/main/java/jaxx/runtime/decorator/JXPathDecorator.java trunk/jaxx-runtime/src/main/java/jaxx/runtime/decorator/MultiJXPathDecorator.java trunk/jaxx-runtime/src/main/java/jaxx/runtime/decorator/PropertyDecorator.java trunk/jaxx-runtime/src/test/java/jaxx/runtime/decorator/Data.java trunk/jaxx-runtime/src/test/java/jaxx/runtime/decorator/DecoratorProviderTest.java trunk/jaxx-runtime/src/test/java/jaxx/runtime/decorator/MultiJXPathDecoratorTest.java Modified: trunk/jaxx-runtime/src/main/java/jaxx/runtime/decorator/DecoratorUtils.java =================================================================== --- trunk/jaxx-runtime/src/main/java/jaxx/runtime/decorator/DecoratorUtils.java 2010-09-04 23:22:35 UTC (rev 2063) +++ trunk/jaxx-runtime/src/main/java/jaxx/runtime/decorator/DecoratorUtils.java 2010-09-06 12:55:58 UTC (rev 2064) @@ -26,8 +26,16 @@ import jaxx.runtime.decorator.JXPathDecorator.Context; import jaxx.runtime.decorator.JXPathDecorator.JXPathComparator; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; -import java.util.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; +import java.util.StringTokenizer; +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** * Some usefull methods on {@link Decorator} to create, and sort data with @@ -49,6 +57,10 @@ */ public class DecoratorUtils { + /** Logger */ + private static final Log log = LogFactory.getLog(DecoratorUtils.class); + + /** * Factory method to instanciate a new {@link PropertyDecorator} for the * given class {@code internlaClass} and a readable property name. @@ -146,6 +158,25 @@ public static <O> void sort(JXPathDecorator<O> decorator, List<O> datas, int pos) { + sort(decorator, datas, pos, false); + } + + /** + * Sort a list of data based on the first token property of a given context + * in a given decorator. + * + * @param <O> type of data to sort + * @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. + * @param reverse flag to sort in reverse order if sets to {@code true} + * @since 2.2 + */ + public static <O> void sort(JXPathDecorator<O> decorator, + List<O> datas, + int pos, + boolean reverse) { Comparator<O> c = null; boolean cachedComparator = false; try { @@ -156,6 +187,11 @@ ((JXPathComparator<O>) c).init(decorator, datas); } Collections.sort(datas, c); + if (reverse) { + + // reverse order + Collections.reverse(datas); + } } finally { if (cachedComparator) { ((JXPathComparator<?>) c).clear(); @@ -171,9 +207,11 @@ int start; while ((start = expression.indexOf("${", end + 1)) > -1) { if (start > end + 1) { + // prefix of next jxpath token buffer.append(expression.substring(end + 1, start)); } + // seek end of jxpath end = expression.indexOf("}", start + 1); if (end == -1) { @@ -182,23 +220,27 @@ start + " : " + expression.substring(start + 2)); } String jxpath = expression.substring(start + 2, end); + // not allowed ${ inside a jxpath token - if (jxpath.indexOf("${") > -1) { + if (jxpath.contains("${")) { throw new IllegalArgumentException( "could not find a ${ inside a jxpath expression at " + "car " + (start + 2) + " : " + jxpath); } + // save the jxpath token lTokens.add(jxpath); + // replace jxpath token in expresion with a string format variable buffer.append('%').append(lTokens.size()); } - if (size > (end + 1)) { + if (size > end + 1) { + // suffix after end jxpath (or all expression if no jxpath) buffer.append(expression.substring(end + 1)); } - return new Context<O>(buffer.toString(), lTokens.toArray( - new String[lTokens.size()])); + String[] tokens = lTokens.toArray(new String[lTokens.size()]); + return new Context<O>(buffer.toString(), tokens); } public static <O> Context<O>[] createMultiJXPathContext( @@ -220,16 +262,32 @@ int nbTokens = tokens.size(); Context<O>[] contexts = newInstance(nbTokens); + if (log.isDebugEnabled()) { + log.debug("Will prepare " + nbTokens + " contexts from [" + expression + "]"); + } 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); + + //replace all '%(index+1)$' pattern with '%(j+1)$' + Pattern p = Pattern.compile("\\%(" + (index + 1) + ")\\$"); + Matcher matcher = p.matcher(str); + String safeStr = matcher.replaceAll("\\%" + (j + 1) + "\\$"); + + if (log.isDebugEnabled()) { + log.debug("[" + (index + 1) + "-->" + (j + 1) + "] " + str + + " transformed to " + safeStr); + } + buffer.append(separatorReplacement).append(safeStr); } + String expr = buffer.substring(separatorReplacement.length()); + if (log.isDebugEnabled()) { + log.debug("context [" + i + "] : " + expr); + } contexts[i] = createJXPathContext( - buffer.substring(separatorReplacement.length())); + expr); } return contexts; } Modified: trunk/jaxx-runtime/src/main/java/jaxx/runtime/decorator/JXPathDecorator.java =================================================================== --- trunk/jaxx-runtime/src/main/java/jaxx/runtime/decorator/JXPathDecorator.java 2010-09-04 23:22:35 UTC (rev 2063) +++ trunk/jaxx-runtime/src/main/java/jaxx/runtime/decorator/JXPathDecorator.java 2010-09-06 12:55:58 UTC (rev 2064) @@ -29,7 +29,11 @@ import org.apache.commons.logging.LogFactory; import java.io.Serializable; -import java.util.*; +import java.util.Arrays; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Map; /** * JXPath decorator based on {@link String#format(String, Object...)} method. @@ -58,21 +62,17 @@ public class JXPathDecorator<O> extends Decorator<O> { private static final long serialVersionUID = 1L; - /** - * Logger - */ + + /** Logger */ private static final Log log = LogFactory.getLog(JXPathDecorator.class); - /** - * the computed context of the decorator - */ + + /** the computed context of the decorator */ protected Context<O> context; - /** - * nb jxpath tokens to compute - */ + + /** nb jxpath tokens to compute */ protected int nbToken; - /** - * the initial expression used to compute the decorator context. - */ + + /** the initial expression used to compute the decorator context. */ protected String initialExpression; protected JXPathDecorator(Class<O> internalClass, @@ -99,13 +99,20 @@ args[i] = getTokenValue(jxcontext, context.tokens[i]); } catch (Exception e) { log.error("can not obtain token " + context.tokens[i] - + "on object " + bean + " for reason " + - e.getMessage(), e); + + "on object " + bean + " for reason " + + e.getMessage(), e); } } - return String.format(context.expression, args); + String result; + try { + result = String.format(context.expression, args); + } catch (Exception eee) { + log.error("Could not format " + context.expression + " with args : " + Arrays.toString(args), eee); + result = ""; + } + return result; } public String getProperty(int pos) { @@ -159,6 +166,7 @@ public static class JXPathComparator<O> implements Comparator<O> { protected Map<O, Comparable<Comparable<?>>> valueCache; + private final String expression; public JXPathComparator(String expression) { @@ -204,11 +212,12 @@ * all variables are compute using using the jxpath tokens. */ protected String expression; - /** - * list of jxpath tokens to apply on expression - */ + + /** list of jxpath tokens to apply on expression */ protected String[] tokens; + protected transient Comparator<O> comparator; + private static final long serialVersionUID = 1L; public Context(String expression, String[] tokens) { @@ -234,15 +243,15 @@ @Override public String toString() { return "<expression:" + expression + ", tokens:" + - Arrays.toString(tokens) + '>'; + Arrays.toString(tokens) + '>'; } } 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 + ']'); + " is out of bound, can be inside [" + + 0 + ',' + decorator.nbToken + ']'); } } } Modified: trunk/jaxx-runtime/src/main/java/jaxx/runtime/decorator/MultiJXPathDecorator.java =================================================================== --- trunk/jaxx-runtime/src/main/java/jaxx/runtime/decorator/MultiJXPathDecorator.java 2010-09-04 23:22:35 UTC (rev 2063) +++ trunk/jaxx-runtime/src/main/java/jaxx/runtime/decorator/MultiJXPathDecorator.java 2010-09-06 12:55:58 UTC (rev 2064) @@ -60,7 +60,7 @@ String separator, String separatorReplacement, Context<O>[] contexts) throws IllegalArgumentException, - NullPointerException { + NullPointerException { super(internalClass, expression, null); this.separator = separator; this.separatorReplacement = separatorReplacement; Modified: trunk/jaxx-runtime/src/main/java/jaxx/runtime/decorator/PropertyDecorator.java =================================================================== --- trunk/jaxx-runtime/src/main/java/jaxx/runtime/decorator/PropertyDecorator.java 2010-09-04 23:22:35 UTC (rev 2063) +++ trunk/jaxx-runtime/src/main/java/jaxx/runtime/decorator/PropertyDecorator.java 2010-09-06 12:55:58 UTC (rev 2064) @@ -39,7 +39,7 @@ * <p/> * For example : * <pre> - * Decorator<Object> d = DecoratorUtils.newPropertyDecorator(PropertyDecorator.class,"expressions"); + * Decorator<Object> d = DecoratorUtils.newPropertyDecorator(PropertyDecorator.class,"property"); * </pre> * * @author tchemit <chemit@codelutin.com> Modified: trunk/jaxx-runtime/src/test/java/jaxx/runtime/decorator/Data.java =================================================================== --- trunk/jaxx-runtime/src/test/java/jaxx/runtime/decorator/Data.java 2010-09-04 23:22:35 UTC (rev 2063) +++ trunk/jaxx-runtime/src/test/java/jaxx/runtime/decorator/Data.java 2010-09-06 12:55:58 UTC (rev 2064) @@ -41,7 +41,6 @@ } Data(int pos, String name) { - super(); this.pos = pos; this.name = name; } Modified: trunk/jaxx-runtime/src/test/java/jaxx/runtime/decorator/DecoratorProviderTest.java =================================================================== --- trunk/jaxx-runtime/src/test/java/jaxx/runtime/decorator/DecoratorProviderTest.java 2010-09-04 23:22:35 UTC (rev 2063) +++ trunk/jaxx-runtime/src/test/java/jaxx/runtime/decorator/DecoratorProviderTest.java 2010-09-06 12:55:58 UTC (rev 2064) @@ -46,7 +46,6 @@ registerPropertyDecorator(File.class, "name"); registerPropertyDecorator(File.class, BY_NAME, "parent"); - registerJXPathDecorator(Class.class, "${simpleName}$s"); registerJXPathDecorator(Class.class, BY_NAME, "${name}$s"); Modified: trunk/jaxx-runtime/src/test/java/jaxx/runtime/decorator/MultiJXPathDecoratorTest.java =================================================================== --- trunk/jaxx-runtime/src/test/java/jaxx/runtime/decorator/MultiJXPathDecoratorTest.java 2010-09-04 23:22:35 UTC (rev 2063) +++ trunk/jaxx-runtime/src/test/java/jaxx/runtime/decorator/MultiJXPathDecoratorTest.java 2010-09-06 12:55:58 UTC (rev 2064) @@ -189,14 +189,14 @@ assertEquals(expected, result); decorator.setContextIndex(1); - assertEquals("%1$d - %2$s %3$s - %3$s", decorator.getExpression()); + assertEquals("%1$d - %2$s %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 %3$s - %2$s - %3$d", decorator.getExpression()); + assertEquals("%1$s %1$s - %2$s - %3$d", decorator.getExpression()); assertTokens("separator", "expression", "nbToken"); expected = String.format(decorator.getExpression(), decorator.getSeparator(), decorator.getExpression(), decorator.getNbToken());
participants (1)
-
tchemit@users.nuiton.org