Author: tchemit Date: 2011-07-31 15:25:21 +0200 (Sun, 31 Jul 2011) New Revision: 2155 Url: http://nuiton.org/repositories/revision/nuiton-utils/2155 Log: Evolution #1594: Update xwork to 2.2.3 (update third-parties) Evolution #1643: New decorator api (from jaxx-runtime project) updates svn properties Added: trunk/nuiton-utils/src/main/java/org/nuiton/util/decorator/ trunk/nuiton-utils/src/main/java/org/nuiton/util/decorator/Decorator.java trunk/nuiton-utils/src/main/java/org/nuiton/util/decorator/DecoratorProvider.java trunk/nuiton-utils/src/main/java/org/nuiton/util/decorator/DecoratorUtils.java trunk/nuiton-utils/src/main/java/org/nuiton/util/decorator/JXPathDecorator.java trunk/nuiton-utils/src/main/java/org/nuiton/util/decorator/MapPropertyHandler.java trunk/nuiton-utils/src/main/java/org/nuiton/util/decorator/MultiJXPathDecorator.java trunk/nuiton-utils/src/main/java/org/nuiton/util/decorator/PropertyDecorator.java trunk/nuiton-utils/src/test/java/org/nuiton/util/decorator/ trunk/nuiton-utils/src/test/java/org/nuiton/util/decorator/Data.java trunk/nuiton-utils/src/test/java/org/nuiton/util/decorator/DecoratorProviderTest.java trunk/nuiton-utils/src/test/java/org/nuiton/util/decorator/JXPathContextTester.java trunk/nuiton-utils/src/test/java/org/nuiton/util/decorator/JXPathDecoratorTest.java trunk/nuiton-utils/src/test/java/org/nuiton/util/decorator/MapPropertyHandlerTest.java trunk/nuiton-utils/src/test/java/org/nuiton/util/decorator/MultiJXPathDecoratorTest.java Modified: trunk/nuiton-utils/pom.xml trunk/nuiton-utils/src/main/java/org/nuiton/util/MatrixMap.java trunk/nuiton-utils/src/test/java/org/nuiton/util/MatrixMapTest.java trunk/nuiton-validator/src/license/THIRD-PARTY.properties Modified: trunk/nuiton-utils/pom.xml =================================================================== --- trunk/nuiton-utils/pom.xml 2011-07-19 16:46:06 UTC (rev 2154) +++ trunk/nuiton-utils/pom.xml 2011-07-31 13:25:21 UTC (rev 2155) @@ -66,6 +66,11 @@ </dependency> <dependency> + <groupId>commons-jxpath</groupId> + <artifactId>commons-jxpath</artifactId> + </dependency> + + <dependency> <groupId>org.nuiton.i18n</groupId> <artifactId>nuiton-i18n</artifactId> </dependency> Modified: trunk/nuiton-utils/src/main/java/org/nuiton/util/MatrixMap.java =================================================================== --- trunk/nuiton-utils/src/main/java/org/nuiton/util/MatrixMap.java 2011-07-19 16:46:06 UTC (rev 2154) +++ trunk/nuiton-utils/src/main/java/org/nuiton/util/MatrixMap.java 2011-07-31 13:25:21 UTC (rev 2155) @@ -1,3 +1,27 @@ +/* + * #%L + * Nuiton Utils :: Nuiton Utils + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2004 - 2011 CodeLutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ package org.nuiton.util; import java.io.Serializable; Property changes on: trunk/nuiton-utils/src/main/java/org/nuiton/util/MatrixMap.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Added: trunk/nuiton-utils/src/main/java/org/nuiton/util/decorator/Decorator.java =================================================================== --- trunk/nuiton-utils/src/main/java/org/nuiton/util/decorator/Decorator.java (rev 0) +++ trunk/nuiton-utils/src/main/java/org/nuiton/util/decorator/Decorator.java 2011-07-31 13:25:21 UTC (rev 2155) @@ -0,0 +1,59 @@ +/* + * #%L + * Nuiton Utils :: Nuiton Utils + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2004 - 2011 CodeLutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ +package org.nuiton.util.decorator; + +import java.io.Serializable; + +/** + * A simple contract to define a String decorator on any java object. + * + * @author tchemit <chemit@codelutin.com> + * @param <O> the type of data to decorate + * @since 2.2.1 + */ +public abstract class Decorator<O> implements Serializable { + + private static final long serialVersionUID = -1L; + + /** Type of the data to decorate */ + protected final Class<O> internalClass; + + public Decorator(Class<O> internalClass) throws NullPointerException { + if (internalClass == null) { + throw new NullPointerException("internalClass can not be null."); + } + this.internalClass = internalClass; + } + + /** + * @param bean the bean to decorate + * @return the string value of the given bean + */ + public abstract String toString(Object bean); + + public Class<O> getInternalClass() { + return internalClass; + } +} Property changes on: trunk/nuiton-utils/src/main/java/org/nuiton/util/decorator/Decorator.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Added: trunk/nuiton-utils/src/main/java/org/nuiton/util/decorator/DecoratorProvider.java =================================================================== --- trunk/nuiton-utils/src/main/java/org/nuiton/util/decorator/DecoratorProvider.java (rev 0) +++ trunk/nuiton-utils/src/main/java/org/nuiton/util/decorator/DecoratorProvider.java 2011-07-31 13:25:21 UTC (rev 2155) @@ -0,0 +1,269 @@ +/* + * #%L + * Nuiton Utils :: Nuiton Utils + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2004 - 2011 CodeLutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ +package org.nuiton.util.decorator; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import java.util.ArrayList; +import java.util.List; + +/** + * A decorator provider. + * <p/> + * Implements the method {@link #loadDecorators()} to fill the decorators + * availables. + * <p/> + * Then can obtain decorator via the methods {@code getDecorator(...)} + * <p/> + * + * @author tchemit <chemit@codelutin.com> + * @since 2.2.1 + */ +public abstract class DecoratorProvider { + + /** Logger */ + private static final Log log = LogFactory.getLog(JXPathDecorator.class); + + /** Registred decorators. */ + protected List<DecoratorContext<?>> decorators; + + public DecoratorProvider() { + loadDecorators(); + } + + /** Load all decorators of the provider */ + protected abstract void loadDecorators(); + + /** + * Obtain a decorator for the given object. + * + * @param object object of decorated object + * @param <O> object of decorated object + * @return the decorator or {@code null} if not found + */ + @SuppressWarnings({"unchecked"}) + public <O> Decorator<O> getDecorator(O object) { + return getDecorator(object, null); + } + + /** + * Obtain a decorator given a object and an extra name to qualify the + * context. + * + * @param object object of decorated object + * @param name extra name to qualify the decorator to use + * @param <O> object of decorated object + * @return the decorator or {@code null} if not found + */ + @SuppressWarnings({"unchecked"}) + public <O> Decorator<O> getDecorator(O object, String name) { + Class<O> k = (Class<O>) object.getClass(); + return getDecorator(k, name); + } + + /** + * Obtain a decorator given a type. + * + * @param type type of decorated object + * @param <O> type of decorated object + * @return the decorator or {@code null} if not found + */ + public <O> Decorator<O> getDecorator(Class<O> type) { + return getDecorator(type, null); + } + + /** + * Obtain a decorator given a type and a extra name. + * + * @param type type of decorated object + * @param name extra name to qualify the decorator to use + * @param <O> type of decorated object + * @return the decorator or {@code null} if not found + */ + public <O> Decorator<O> getDecorator(Class<O> type, String name) { + DecoratorContext<O> d = getDecoratorContext(type, name); + return d == null ? null : d.getDecorator(); + } + + public void reload() { + clear(); + loadDecorators(); + } + + public void clear() { + if (decorators != null) { + decorators.clear(); + } + } + + protected void registerPropertyDecorator(Class<?> klass, + String expression) { + registerPropertyDecorator(klass, null, expression); + } + + protected void registerJXPathDecorator(Class<?> klass, String expression) { + registerJXPathDecorator(klass, null, expression); + } + + protected void registerMultiJXPathDecorator(Class<?> klass, + String expression, + String separator, + String separatorReplacement) { + registerMultiJXPathDecorator(klass, null, expression, separator, + separatorReplacement); + } + + protected void registerPropertyDecorator(Class<?> klass, + String name, + String expression) { + Decorator<?> decorator = + DecoratorUtils.newPropertyDecorator(klass, expression); + registerDecorator(name, decorator); + } + + protected void registerJXPathDecorator(Class<?> klass, + String name, + String expression) { + Decorator<?> decorator = + DecoratorUtils.newJXPathDecorator(klass, expression); + registerDecorator(name, decorator); + } + + protected void registerMultiJXPathDecorator(Class<?> klass, + String name, + String expression, + String separator, + String separatorReplacement) { + Decorator<?> decorator = DecoratorUtils.newMultiJXPathDecorator( + klass, expression, separator, separatorReplacement + ); + registerDecorator(name, decorator); + } + + protected void registerDecorator(Decorator<?> decorator) { + registerDecorator(null, decorator); + } + + /** + * Register a new decorator in the cache of the provider. + * + * @param <T> type of data decorated + * @param context the name decorator + * @param decorator the decorator to register + */ + protected <T> void registerDecorator(String context, + Decorator<T> decorator) { + + // obtain the decorator context + DecoratorContext<?> result = + getDecoratorContext(decorator.getInternalClass(), context); + + if (result != null) { + throw new IllegalArgumentException( + "there is an already register decorator with context " + + result); + } + + DecoratorContext<T> decoratorContext = + new DecoratorContext<T>(context, decorator); + if (log.isDebugEnabled()) { + log.debug(decoratorContext); + } + getDecorators().add(decoratorContext); + } + + protected List<DecoratorContext<?>> getDecorators() { + if (decorators == null) { + decorators = new ArrayList<DecoratorContext<?>>(); + } + return decorators; + } + + @SuppressWarnings({"unchecked"}) + protected <T> DecoratorContext<T> getDecoratorContext(Class<T> type, + String context) { + DecoratorContext<T> result = null; + if (decorators != null) { + for (DecoratorContext<?> d : decorators) { + if (type == null) { + if (d.accept(context)) { + result = (DecoratorContext<T>) d; + break; + } + continue; + } + if (d.accept(type, context)) { + result = (DecoratorContext<T>) d; + break; + } + } + } + return result; + } + + public static class DecoratorContext<T> { + + /** the context name of the decorator */ + final String context; + + /** the decorator */ + final Decorator<T> decorator; + + public DecoratorContext(String context, Decorator<T> decorator) { + this.context = context; + this.decorator = decorator; + } + + public String getContext() { + return context; + } + + public Decorator<T> getDecorator() { + return decorator; + } + + public Class<T> getType() { + return decorator.getInternalClass(); + } + + public boolean accept(Class<?> type, String context) { + boolean accept = getType().isAssignableFrom(type) && accept(context); + return accept; + } + + public boolean accept(String context) { + return this.context == null && context == null || + this.context != null && this.context.equals(context); + } + + @Override + public String toString() { + return super.toString() + "<type: " + getType().getName() + + ", context :" + context + ">"; + } + } + +} Property changes on: trunk/nuiton-utils/src/main/java/org/nuiton/util/decorator/DecoratorProvider.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Added: trunk/nuiton-utils/src/main/java/org/nuiton/util/decorator/DecoratorUtils.java =================================================================== --- trunk/nuiton-utils/src/main/java/org/nuiton/util/decorator/DecoratorUtils.java (rev 0) +++ trunk/nuiton-utils/src/main/java/org/nuiton/util/decorator/DecoratorUtils.java 2011-07-31 13:25:21 UTC (rev 2155) @@ -0,0 +1,300 @@ +/* + * #%L + * Nuiton Utils :: Nuiton Utils + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2004 - 2011 CodeLutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ +package org.nuiton.util.decorator; + +import org.nuiton.util.decorator.JXPathDecorator.Context; +import org.nuiton.util.decorator.JXPathDecorator.JXPathComparator; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +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 + * decorators. + * <p/> + * To create a new decorator, use one of the methods : <ul> <li>{@link + * #newPropertyDecorator(Class, String)}</li> <li>{@link + * #newJXPathDecorator(Class, String)}</li> <li> + * {@link #newMultiJXPathDecorator(Class, String, String)})</li> + * <li>{@link #newMultiJXPathDecorator(Class, String,String, String)})</li> + * </ul> + * <p/> + * To sort a list of data, using a {@link JXPathDecorator}, use the method + * {@link #sort(JXPathDecorator, List, int)}. + * <p/> + * + * @author tchemit <chemit@codelutiln.com> + * @since 2.2.1 + */ +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. + * + * @param internalClass the class of the objects decorated by the new + * decorator + * @param property the property + * @param <O> the generic type of class to be decorated by the new + * decorator + * @return the new instanciated decorator + * @throws IllegalArgumentException if the expression is not valid, says: + * <p/> + * - a missing right brace was detected. + * <p/> + * - a ${ was found in a jxpath token. + * @throws NullPointerException if internalClass parameter is null. + */ + public static <O> PropertyDecorator<O> newPropertyDecorator( + Class<O> internalClass, + String property) + throws IllegalArgumentException, NullPointerException { + return new PropertyDecorator<O>(internalClass, property); + } + + /** + * Factory method to instanciate a new {@link JXPathDecorator} for the given + * class {@code internalClass} and expression. + * + * @param internalClass the class of the objects decorated by the new + * decorator + * @param expression the expression to use to decorated objects + * @param <O> the generic type of class to be decorated by the new + * decorator + * @return the new instanciated decorator + * @throws IllegalArgumentException if the expression is not valid, says: + * <p/> + * - a missing right brace was detected. + * <p/> + * - a ${ was found in a jxpath token. + * @throws NullPointerException if internalClass parameter is null. + */ + public static <O> JXPathDecorator<O> newJXPathDecorator( + Class<O> internalClass, + String expression) + throws IllegalArgumentException, NullPointerException { + + Context<O> context = createJXPathContext(expression); + return new JXPathDecorator<O>(internalClass, expression, context); + } + + public static <O> MultiJXPathDecorator<O> newMultiJXPathDecorator( + Class<O> internalClass, + String expression, + String separator) + throws IllegalArgumentException, NullPointerException { + + MultiJXPathDecorator<O> decorator = newMultiJXPathDecorator( + internalClass, + expression, + separator, + separator); + return decorator; + } + + public static <O> MultiJXPathDecorator<O> newMultiJXPathDecorator( + Class<O> internalClass, + String expression, + String separator, + String separatorReplacement) + throws IllegalArgumentException, NullPointerException { + + Context<O>[] contexts = createMultiJXPathContext( + expression, + separator, + separatorReplacement); + + return new MultiJXPathDecorator<O>( + internalClass, + expression, + separator, + separatorReplacement, + contexts); + } + + /** + * 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. + */ + 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 { + c = decorator.getComparator(pos); + cachedComparator = c instanceof JXPathComparator<?>; + + if (cachedComparator) { + ((JXPathComparator<O>) c).init(decorator, datas); + } + Collections.sort(datas, c); + if (reverse) { + + // reverse order + Collections.reverse(datas); + } + } finally { + if (cachedComparator) { + ((JXPathComparator<?>) c).clear(); + } + } + } + + public static <O> Context<O> createJXPathContext(String expression) { + List<String> lTokens = new ArrayList<String>(); + StringBuilder buffer = new StringBuilder(); + int size = expression.length(); + int end = -1; + 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) { + throw new IllegalArgumentException( + "could not find the rigth brace starting at car " + + start + " : " + expression.substring(start + 2)); + } + String jxpath = expression.substring(start + 2, end); + + // not allowed ${ inside a jxpath token + 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) { + + // suffix after end jxpath (or all expression if no jxpath) + buffer.append(expression.substring(end + 1)); + } + String[] tokens = lTokens.toArray(new String[lTokens.size()]); + return new Context<O>(buffer.toString(), tokens); + } + + public static <O> Context<O>[] createMultiJXPathContext( + String expression, + String separator, + String separatorReplacement) { + int sep = expression.indexOf(separator); + if (sep == -1) { + Context<O>[] result = newInstance(1); + result[0] = createJXPathContext(expression); + return result; + } + + List<String> tokens = new ArrayList<String>(); + StringTokenizer stk = new StringTokenizer(expression, separator); + while (stk.hasMoreTokens()) { + tokens.add(stk.nextToken()); + } + + 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); + + //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( + expr); + } + return contexts; + } + + @SuppressWarnings("unchecked") + protected static <O> Context<O>[] newInstance(int size) { + // fixme how to instanciate a typed array with no checking warning ? + return new Context[size]; + } +} Property changes on: trunk/nuiton-utils/src/main/java/org/nuiton/util/decorator/DecoratorUtils.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Added: trunk/nuiton-utils/src/main/java/org/nuiton/util/decorator/JXPathDecorator.java =================================================================== --- trunk/nuiton-utils/src/main/java/org/nuiton/util/decorator/JXPathDecorator.java (rev 0) +++ trunk/nuiton-utils/src/main/java/org/nuiton/util/decorator/JXPathDecorator.java 2011-07-31 13:25:21 UTC (rev 2155) @@ -0,0 +1,263 @@ +/* + * #%L + * Nuiton Utils :: Nuiton Utils + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2004 - 2011 CodeLutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ +package org.nuiton.util.decorator; + +import org.apache.commons.jxpath.JXPathContext; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import java.io.Serializable; +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. + * <p/> + * To use it, give to him a expression where all jxpath to apply on bean are + * boxed in <code>${}</code>. + * <p/> + * After the jxpath token you must specifiy the formatter to apply of the + * jxpath token. + * <p/> + * For example : + * <pre> + * Decorator<Object> d = DecoratorUtils.newJXPathDecorator( + * JXPathDecorator.class,"expr = ${expressions}$s"); + * assert "expr = %1$s" == d.getExpression(); + * assert 1 == d.getNbToken(); + * assert java.util.Arrays.asList("expression") == d.getTokens(); + * assert "expr = %1$s" == d.toString(d); + * </pre> + * + * @param <O> type of data to decorate + * @author tchemit <chemit@codelutin.com> + * @see Decorator + * @since 2.2.1 + */ +public class JXPathDecorator<O> extends Decorator<O> { + + private static final long serialVersionUID = 1L; + + /** Logger */ + private static final Log log = LogFactory.getLog(JXPathDecorator.class); + + /** the computed context of the decorator */ + protected Context<O> context; + + /** nb jxpath tokens to compute */ + protected int nbToken; + + /** the initial expression used to compute the decorator context. */ + protected String initialExpression; + + protected JXPathDecorator(Class<O> internalClass, + String expression, + Context<O> context) + throws IllegalArgumentException, NullPointerException { + super(internalClass); + initialExpression = expression; + if (context != null) { + setContext(context); + } + } + + @Override + 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++) { + try { + args[i] = getTokenValue(jxcontext, context.tokens[i]); + } catch (Exception e) { + if (log.isErrorEnabled()) { + log.error("can not obtain token " + context.tokens[i] + + " on object of type " + + bean.getClass().getName() + + " for reason " + e.getMessage(), e); + } + + } + } + + String result; + try { + result = String.format(context.expression, args); + } catch (Exception eee) { + if (log.isErrorEnabled()) { + log.error("Could not format " + context.expression + "" + + " with args : " + Arrays.toString(args), eee); + } + result = ""; + } + return result; + } + + 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 void setContext(Context<O> context) { + this.context = context; + nbToken = context.tokens.length; + // always reset comparator + //this.context.comparator = null; + if (log.isDebugEnabled()) { + log.debug(context); + } + } + + @SuppressWarnings({"unchecked"}) + protected Comparator<O> getComparator(int pos) { + ensureTokenIndex(this, pos); + return context.getComparator(pos); + } + + @SuppressWarnings({"unchecked"}) + protected Comparable<Comparable<?>> getTokenValue(JXPathContext jxcontext, + String token) { + // assume all values are comparable + return (Comparable<Comparable<?>>) jxcontext.getValue(token); + } + + public static class JXPathComparator<O> implements Comparator<O> { + + protected Map<O, Comparable<Comparable<?>>> valueCache; + + private final String expression; + + public JXPathComparator(String expression) { + this.expression = expression; + valueCache = new HashMap<O, Comparable<Comparable<?>>>(); + } + + @Override + public int compare(O o1, O o2) { + Comparable<Comparable<?>> c1 = valueCache.get(o1); + Comparable<Comparable<?>> c2 = valueCache.get(o2); + if (c1 == null) { + if (c2 == null) { + return 0; + } + return 1; + } + if (c2 == null) { + return -1; + } + return c1.compareTo(c2); + } + + public void clear() { + valueCache.clear(); + } + + public void init(JXPathDecorator<O> decorator, List<O> datas) { + clear(); + for (O data : datas) { + JXPathContext jxcontext = JXPathContext.newContext(data); + Comparable<Comparable<?>> key; + key = decorator.getTokenValue(jxcontext, expression); + valueCache.put(data, key); + } + } + } + + public static class Context<O> 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<O> 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<O> getComparator(int pos) { + if (comparator == null) { + comparator = new JXPathComparator<O>(tokens[pos]); + } + return comparator; + } + + public void setComparator(Comparator<O> comparator) { + this.comparator = comparator; + } + + @Override + public String toString() { + return "<expression:" + expression + ", 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 + ']'); + } + } +} Property changes on: trunk/nuiton-utils/src/main/java/org/nuiton/util/decorator/JXPathDecorator.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Added: trunk/nuiton-utils/src/main/java/org/nuiton/util/decorator/MapPropertyHandler.java =================================================================== --- trunk/nuiton-utils/src/main/java/org/nuiton/util/decorator/MapPropertyHandler.java (rev 0) +++ trunk/nuiton-utils/src/main/java/org/nuiton/util/decorator/MapPropertyHandler.java 2011-07-31 13:25:21 UTC (rev 2155) @@ -0,0 +1,180 @@ +/* + * #%L + * Nuiton Utils :: Nuiton Utils + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2004 - 2011 CodeLutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ +package org.nuiton.util.decorator; + +import org.apache.commons.jxpath.DynamicPropertyHandler; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import java.util.Collection; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; + +/** + * A extended handler to deal with map in JXPath contexts. + * <p/> + * The basic one in JXPath api only deals with map keys as string. + * <p/> + * We offers a hook in method {@link #getKey(Object)} to obtain a string + * representation of a real object in map (key or value). + * <p/> + * More over, you can also access directly to a key or a value, using this + * syntax : + * <p/> + * <pre>context.getValue(".[@name='key:programme2']")</pre> + * <pre>context.getValue(".[@name='value:programme2']")</pre> + * <p/> + * If the values are iterable, then will scan inot it when looking for a direct + * value. + * + * @author tchemit <chemit@codelutin.com> + * @see DynamicPropertyHandler + * @since 2.2.1 + */ +public class MapPropertyHandler implements DynamicPropertyHandler { + + /** Logger */ + private static final Log log = + LogFactory.getLog(MapPropertyHandler.class); + + @Override + public String[] getPropertyNames(Object object) { + Map<?, ?> map = (Map<?, ?>) object; + Set<?> set = map.keySet(); + String[] names = new String[set.size()]; + Iterator<?> it = set.iterator(); + for (int i = 0; i < names.length; i++) { + Object o = it.next(); + names[i] = getKey(o); + } + return names; + } + + @Override + public Object getProperty(Object object, String propertyName) { + Map<?, ?> map = (Map<?, ?>) object; + boolean getKey = false; + Object property0; + if (propertyName.startsWith("value:")) { + propertyName = propertyName.substring(6); + if (log.isDebugEnabled()) { + log.debug("property value name " + propertyName); + } + property0 = getPropertyValue(map, propertyName); + if (log.isDebugEnabled()) { + log.debug("property value = " + property0); + } + return property0; + } + if (propertyName.startsWith("key:")) { + propertyName = propertyName.substring(4); + getKey = true; + } + property0 = getPropertyKey(map, propertyName); + Object result = null; + if (property0 != null) { + if (getKey) { + result = property0; + } else { + result = map.get(property0); + } + } + return result; + } + + @Override + public void setProperty(Object object, String propertyName, Object value) { + Map map = (Map) object; + Object property0 = getPropertyKey(map, propertyName); + if (property0 != null) { + map.put(property0, value); + } + } + + /** + * Obtain the key from the map keys which matches the given {@code key}. + * <p/> + * To compare object ot string, please refers to the method {@link + * #getKey(Object)}. + * + * @param map the map to scan + * @param key the string representation of the required key as object + * @return the found key, or {@code null} if not found. + */ + public Object getPropertyKey(Map<?, ?> map, String key) { + Set<?> set = map.keySet(); + for (Object o : set) { + String k = getKey(o); + if (key.equals(k)) { + return o; + } + } + return null; + } + + /** + * Obtain the value from the map values which matches the given {@code + * value}. + * <p/> + * To compare object to string, please refer to the method {@link + * #getKey(Object)}. + * + * @param map the map to scan + * @param value the string representation of the value + * @return the found value, or {@code null} if not found.} + */ + public Object getPropertyValue(Map<?, ?> map, String value) { + Collection<?> set = map.values(); + for (Object o : set) { + if (o instanceof Iterable<?>) { + Iterable<?> c = (Iterable<?>) o; + for (Object oo : c) { + String k = getKey(oo); + if (value.equals(k)) { + return oo; + } + } + continue; + } + String k = getKey(o); + if (value.equals(k)) { + return o; + } + } + return null; + } + + /** + * Obtain a string representation of an object. + * + * @param o the object to decorate + * @return the string representation of the object + */ + protected String getKey(Object o) { + String k = String.valueOf(o); + return k; + } +} Property changes on: trunk/nuiton-utils/src/main/java/org/nuiton/util/decorator/MapPropertyHandler.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Added: trunk/nuiton-utils/src/main/java/org/nuiton/util/decorator/MultiJXPathDecorator.java =================================================================== --- trunk/nuiton-utils/src/main/java/org/nuiton/util/decorator/MultiJXPathDecorator.java (rev 0) +++ trunk/nuiton-utils/src/main/java/org/nuiton/util/decorator/MultiJXPathDecorator.java 2011-07-31 13:25:21 UTC (rev 2155) @@ -0,0 +1,125 @@ +/* + * #%L + * Nuiton Utils :: Nuiton Utils + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2004 - 2011 CodeLutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ +package org.nuiton.util.decorator; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import java.util.Comparator; + +/** + * {@link JXPathDecorator} implementation with multiple contexts. + * + * @param <O> type of data to decorate + * @author tchemit <chemit@codelutin.com> + * @see Decorator + * @since 2.2.1 + */ +public class MultiJXPathDecorator<O> extends JXPathDecorator<O> { + + private static final long serialVersionUID = 1L; + + /** Logger */ + private static final Log log = + LogFactory.getLog(MultiJXPathDecorator.class); + + /** Contexts of the decorator */ + protected Context<O>[] contexts; + + /** context separator */ + protected String separator; + + /** context separator replacement */ + protected String separatorReplacement; + + protected MultiJXPathDecorator( + Class<O> internalClass, + String expression, + String separator, + String separatorReplacement, + Context<O>[] contexts) throws IllegalArgumentException, + NullPointerException { + super(internalClass, expression, null); + this.separator = separator; + this.separatorReplacement = separatorReplacement; + this.contexts = contexts; + + setContextIndex(0); + + if (log.isDebugEnabled()) { + log.debug(expression + " --> " + context); + } + } + + protected MultiJXPathDecorator( + Class<O> internalClass, + String expression, + String separator, + String separatorReplacement) throws IllegalArgumentException, + NullPointerException { + this(internalClass, + expression, + separator, + separatorReplacement, + DecoratorUtils.<O>createMultiJXPathContext(expression, + separator, + separatorReplacement) + ); + } + + 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); + Context<O> context1 = contexts[pos]; + return context1.getComparator(0); + } + + protected 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 + "]"); + } + } +} Property changes on: trunk/nuiton-utils/src/main/java/org/nuiton/util/decorator/MultiJXPathDecorator.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Added: trunk/nuiton-utils/src/main/java/org/nuiton/util/decorator/PropertyDecorator.java =================================================================== --- trunk/nuiton-utils/src/main/java/org/nuiton/util/decorator/PropertyDecorator.java (rev 0) +++ trunk/nuiton-utils/src/main/java/org/nuiton/util/decorator/PropertyDecorator.java 2011-07-31 13:25:21 UTC (rev 2155) @@ -0,0 +1,101 @@ +/* + * #%L + * Nuiton Utils :: Nuiton Utils + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2004 - 2011 CodeLutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ +package org.nuiton.util.decorator; + +import org.apache.commons.beanutils.PropertyUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import java.beans.PropertyDescriptor; +import java.lang.reflect.Method; + +/** + * Simple property decorator based on {@link String#format(String, Object...)} + * method. + * <p/> + * To use it, give him a class and the property name to render. + * <p/> + * For example : + * <pre> + * Decorator<Object> d = DecoratorUtils.newPropertyDecorator(PropertyDecorator.class,"property"); + * </pre> + * + * @author tchemit <chemit@codelutin.com> + * @param <O> type of data to decorate + * @see Decorator + * @since 2.2.1 + */ +public class PropertyDecorator<O> extends Decorator<O> { + + private static final long serialVersionUID = 1L; + + /** Logger */ + static private final Log log = LogFactory.getLog(PropertyDecorator.class); + + /** name of property */ + protected String property; + + protected transient Method m; + + @Override + public String toString(Object bean) { + try { + return getM().invoke(bean) + ""; + } catch (Exception e) { + log.error("could not convert for reason : " + e, e); + return ""; + } + } + + public String getProperty() { + return property; + } + + protected PropertyDecorator(Class<O> internalClass, + String property) throws NullPointerException { + super(internalClass); + if (property == null) { + throw new NullPointerException("property can not be null."); + } + this.property = property; + // init method + getM(); + } + + protected Method getM() { + if (m == null) { + for (PropertyDescriptor propertyDescriptor : PropertyUtils.getPropertyDescriptors(internalClass)) { + if (propertyDescriptor.getName().equals(property)) { + m = propertyDescriptor.getReadMethod(); + break; + } + } + if (m == null) { + throw new IllegalArgumentException("could not find the property " + property + " in " + internalClass); + } + } + return m; + } +} Property changes on: trunk/nuiton-utils/src/main/java/org/nuiton/util/decorator/PropertyDecorator.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Modified: trunk/nuiton-utils/src/test/java/org/nuiton/util/MatrixMapTest.java =================================================================== --- trunk/nuiton-utils/src/test/java/org/nuiton/util/MatrixMapTest.java 2011-07-19 16:46:06 UTC (rev 2154) +++ trunk/nuiton-utils/src/test/java/org/nuiton/util/MatrixMapTest.java 2011-07-31 13:25:21 UTC (rev 2155) @@ -1,4 +1,28 @@ /* + * #%L + * Nuiton Utils :: Nuiton Utils + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2004 - 2011 CodeLutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ +/* * Copyright (c) 2011 poussin. All rights reserved. * * This program is free software: you can redistribute it and/or modify Property changes on: trunk/nuiton-utils/src/test/java/org/nuiton/util/MatrixMapTest.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Added: trunk/nuiton-utils/src/test/java/org/nuiton/util/decorator/Data.java =================================================================== --- trunk/nuiton-utils/src/test/java/org/nuiton/util/decorator/Data.java (rev 0) +++ trunk/nuiton-utils/src/test/java/org/nuiton/util/decorator/Data.java 2011-07-31 13:25:21 UTC (rev 2155) @@ -0,0 +1,61 @@ +/* + * #%L + * Nuiton Utils :: Nuiton Utils + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2004 - 2011 CodeLutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ +package org.nuiton.util.decorator; + +import java.util.ArrayList; +import java.util.List; + +public class Data { + + int pos; + + String name; + + protected static List<Data> generate(int nb) { + List<Data> datas = new ArrayList<Data>(nb); + for (int i = 0; i < nb; i++) { + datas.add(new Data(i, "name_" + (nb - i))); + } + return datas; + } + + Data(int pos, String name) { + this.pos = pos; + this.name = name; + } + + public int getPos() { + return pos; + } + + public String getName() { + return name; + } + + @Override + public String toString() { + return "Data{pos=" + pos + ", name=\'" + name + '\'' + '}'; + } +} Property changes on: trunk/nuiton-utils/src/test/java/org/nuiton/util/decorator/Data.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Added: trunk/nuiton-utils/src/test/java/org/nuiton/util/decorator/DecoratorProviderTest.java =================================================================== --- trunk/nuiton-utils/src/test/java/org/nuiton/util/decorator/DecoratorProviderTest.java (rev 0) +++ trunk/nuiton-utils/src/test/java/org/nuiton/util/decorator/DecoratorProviderTest.java 2011-07-31 13:25:21 UTC (rev 2155) @@ -0,0 +1,176 @@ +/* + * #%L + * Nuiton Utils :: Nuiton Utils + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2004 - 2011 CodeLutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ +package org.nuiton.util.decorator; + +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; + +import java.io.File; + +/** + * User: chemit + * Date: 28 oct. 2009 + * Time: 21:28:46 + */ +public class DecoratorProviderTest { + private static final String BY_NAME = "name"; + + static class MyDecoratorProvider extends DecoratorProvider { + + @Override + protected void loadDecorators() { + + registerPropertyDecorator(File.class, "name"); + registerPropertyDecorator(File.class, BY_NAME, "parent"); + + registerJXPathDecorator(Class.class, "${simpleName}$s"); + registerJXPathDecorator(Class.class, BY_NAME, "${name}$s"); + + registerMultiJXPathDecorator(Data.class, "${name}$s", "-", " "); + registerMultiJXPathDecorator(Data.class, BY_NAME, "${pos}$d", "-", " "); + } + } + + static DecoratorProvider provider; + + @BeforeClass + public static void beforeTest() throws Exception { + provider = new MyDecoratorProvider(); + } + + @Test + public void testGetDecoratorByObject() throws Exception { + + File f = new File("myFile"); + Data d = new Data(0, "name"); + Class<?> k = File.class; + + Decorator<File> fileDecorator = provider.getDecorator(f); + Assert.assertNotNull(fileDecorator); + Assert.assertEquals(File.class, fileDecorator.getInternalClass()); + Assert.assertEquals("myFile", fileDecorator.toString(f)); + + Decorator<?> classDecorator = provider.getDecorator(Class.class); + Assert.assertNotNull(classDecorator); + Assert.assertEquals(Class.class, classDecorator.getInternalClass()); + Assert.assertEquals("File", classDecorator.toString(k)); + + Decorator<Data> dataDecorator = provider.getDecorator(d); + Assert.assertNotNull(dataDecorator); + Assert.assertEquals(Data.class, dataDecorator.getInternalClass()); + Assert.assertEquals("name", dataDecorator.toString(d)); + } + + @Test + public void testGetDecoratorByObjectAndName() throws Exception { + + File f = new File("myFile"); + Data d = new Data(0, "name"); + Class<?> k = File.class; + + Decorator<File> fileDecorator = provider.getDecorator(f, BY_NAME); + Assert.assertNotNull(fileDecorator); + Assert.assertEquals(File.class, fileDecorator.getInternalClass()); + Assert.assertEquals("null", fileDecorator.toString(f)); + + Decorator<Class> classDecorator = provider.getDecorator(Class.class, BY_NAME); + Assert.assertNotNull(classDecorator); + Assert.assertEquals(Class.class, classDecorator.getInternalClass()); + Assert.assertEquals("java.io.File", classDecorator.toString(k)); + + + Decorator<Data> dataDecorator = provider.getDecorator(d, BY_NAME); + Assert.assertNotNull(dataDecorator); + Assert.assertEquals(Data.class, dataDecorator.getInternalClass()); + Assert.assertEquals("0", dataDecorator.toString(d)); + } + + @Test + public void testGetDecoratorByType() throws Exception { + + File f = new File("myFile"); + Data d = new Data(0, "name"); + Class<?> k = File.class; + + Decorator<File> fileDecorator = provider.getDecorator(File.class); + Assert.assertNotNull(fileDecorator); + Assert.assertEquals(File.class, fileDecorator.getInternalClass()); + Assert.assertEquals("myFile", fileDecorator.toString(f)); + + Decorator<Class> classDecorator = provider.getDecorator(Class.class); + Assert.assertNotNull(classDecorator); + Assert.assertEquals(Class.class, classDecorator.getInternalClass()); + Assert.assertEquals("File", classDecorator.toString(k)); + + Decorator<Data> dataDecorator = provider.getDecorator(Data.class); + Assert.assertNotNull(dataDecorator); + Assert.assertEquals(Data.class, dataDecorator.getInternalClass()); + Assert.assertEquals("name", dataDecorator.toString(d)); + } + + @Test + public void testGetDecoratorByTypeAndName() throws Exception { + File f = new File("myFile"); + Data d = new Data(0, "name"); + Class<?> k = File.class; + + Decorator<File> fileDecorator = provider.getDecorator(File.class, BY_NAME); + Assert.assertNotNull(fileDecorator); + Assert.assertEquals(File.class, fileDecorator.getInternalClass()); + Assert.assertEquals("null", fileDecorator.toString(f)); + + Decorator<Class> classDecorator = provider.getDecorator(Class.class, BY_NAME); + Assert.assertNotNull(classDecorator); + Assert.assertEquals(Class.class, classDecorator.getInternalClass()); + Assert.assertEquals("java.io.File", classDecorator.toString(k)); + + + Decorator<Data> dataDecorator = provider.getDecorator(Data.class, BY_NAME); + Assert.assertNotNull(dataDecorator); + Assert.assertEquals(Data.class, dataDecorator.getInternalClass()); + Assert.assertEquals("0", dataDecorator.toString(d)); + } + + + @Test + public void testReload() throws Exception { + + int nb = provider.getDecorators().size(); + Assert.assertTrue(nb > 0); + + provider.reload(); + + Assert.assertEquals(nb, provider.getDecorators().size()); + } + + @Test + public void testClear() throws Exception { + provider.clear(); + + Assert.assertTrue(provider.getDecorators().isEmpty()); + } + +} Property changes on: trunk/nuiton-utils/src/test/java/org/nuiton/util/decorator/DecoratorProviderTest.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Added: trunk/nuiton-utils/src/test/java/org/nuiton/util/decorator/JXPathContextTester.java =================================================================== --- trunk/nuiton-utils/src/test/java/org/nuiton/util/decorator/JXPathContextTester.java (rev 0) +++ trunk/nuiton-utils/src/test/java/org/nuiton/util/decorator/JXPathContextTester.java 2011-07-31 13:25:21 UTC (rev 2155) @@ -0,0 +1,57 @@ +/* + * #%L + * Nuiton Utils :: Nuiton Utils + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2004 - 2011 CodeLutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ +package org.nuiton.util.decorator; + +import org.apache.commons.jxpath.JXPathContext; +import org.junit.After; +import org.junit.Assert; + +/** + * A simple class to test JXPath context. + * + * @author tchemit <chemit@codelutin.com> + * @since 2.0.1 + */ +public abstract class JXPathContextTester { + + JXPathContext context; + + @After + public void after() { + context = null; + + } + + protected void newContext(Object o) { + context = JXPathContext.newContext(o); + } + + protected <T> T getValue(String path) { + Assert.assertNotNull("pas de context initialisé", context); + Object value = context.getValue(path); + return (T) value; + } + +} Property changes on: trunk/nuiton-utils/src/test/java/org/nuiton/util/decorator/JXPathContextTester.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Added: trunk/nuiton-utils/src/test/java/org/nuiton/util/decorator/JXPathDecoratorTest.java =================================================================== --- trunk/nuiton-utils/src/test/java/org/nuiton/util/decorator/JXPathDecoratorTest.java (rev 0) +++ trunk/nuiton-utils/src/test/java/org/nuiton/util/decorator/JXPathDecoratorTest.java 2011-07-31 13:25:21 UTC (rev 2155) @@ -0,0 +1,173 @@ +/* + * #%L + * Nuiton Utils :: Nuiton Utils + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2004 - 2011 CodeLutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ +package org.nuiton.util.decorator; + +import org.junit.After; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +import static org.junit.Assert.assertEquals; + +/** + * @author tchemit <chemit@codelutin.com> + * @since 1.7.2 (was previously {@code jaxx.runtime.JXPathDecoratorTest}). + */ +public class JXPathDecoratorTest { + + + protected JXPathDecorator<?> decorator; + + protected String expected; + + protected String result; + + @After + public void after() { + decorator = null; + } + + @Test(expected = NullPointerException.class) + public void testNullInternalClass() throws Exception { + decorator = DecoratorUtils.newJXPathDecorator(null, "hello"); + } + + @Test(expected = IllegalArgumentException.class) + public void testMissingRightBrace() throws Exception { + decorator = DecoratorUtils.newJXPathDecorator(Object.class, "${haha"); + } + + @Test(expected = IllegalArgumentException.class) + public void testMissingRightBrace2() throws Exception { + decorator = DecoratorUtils.newJXPathDecorator(Object.class, "${haha${hum}"); + } + + @Test + public void testNullBean() throws Exception { + decorator = DecoratorUtils.newJXPathDecorator(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 testNoJXPath() throws Exception { + decorator = DecoratorUtils.newJXPathDecorator(Object.class, "hello"); + expected = "hello"; + assertEquals(expected, decorator.getExpression()); + assertEquals(0, decorator.nbToken); + assertEquals(0, decorator.getTokens().length); + + result = decorator.toString(this); + assertEquals(expected, result); + } + + @Test + public void testDecorator() throws Exception { + + decorator = DecoratorUtils.newJXPathDecorator(JXPathDecorator.class, "${expression}$s - ${nbToken}$d"); + assertEquals("%1$s - %2$d", decorator.getExpression()); + assertDecoratorInternal(); + + decorator = DecoratorUtils.newJXPathDecorator(JXPathDecorator.class, "${expression}${nbToken}"); + assertEquals("%1%2", decorator.getExpression()); + assertDecoratorInternal(); + + decorator = DecoratorUtils.newJXPathDecorator(JXPathDecorator.class, "before ${expression}$s - ${nbToken}$d after"); + assertEquals("before %1$s - %2$d after", decorator.getExpression()); + assertDecoratorInternal(); + + decorator = DecoratorUtils.newJXPathDecorator(JXPathDecorator.class, "before${expression}$s-${nbToken}$dafter"); + assertEquals("before%1$s-%2$dafter", decorator.getExpression()); + assertDecoratorInternal(); + } + + @Test + public void testDecoratorEspcapeCharacters() throws Exception { + + decorator = DecoratorUtils.newJXPathDecorator(JXPathDecorator.class, "(${expression}$s) - ${nbToken}$d"); + assertEquals("(%1$s) - %2$d", decorator.getExpression()); + String s = decorator.toString(decorator); + System.out.println("s=" + s); + assertDecoratorInternal(); + + } + + @Test + public void testSort() throws Exception { + + List<Data> datas = Data.generate(10); + + JXPathDecorator<Data> d = DecoratorUtils.newJXPathDecorator(Data.class, "${pos}$d ${name}$s"); + + List<Data> sortData = new ArrayList<Data>(datas); + DecoratorUtils.sort(d, sortData, 0); + for (int i = 0; i < datas.size(); i++) { + Data data = datas.get(i); + Data sData = sortData.get(i); + assertEquals(data, sData); + } + Collections.sort(datas, new Comparator<Data>() { + @Override + public int compare(Data o1, Data o2) { + return o1.name.compareTo(o2.name); + } + }); + JXPathDecorator.Context<Data> context = d.context; + context.setComparator(null); + DecoratorUtils.sort(d, sortData, 1); + for (int i = 0; i < datas.size(); i++) { + Data data = datas.get(i); + Data sData = sortData.get(i); + assertEquals(data, sData); + } + } + + + 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]); + } + +} Property changes on: trunk/nuiton-utils/src/test/java/org/nuiton/util/decorator/JXPathDecoratorTest.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Added: trunk/nuiton-utils/src/test/java/org/nuiton/util/decorator/MapPropertyHandlerTest.java =================================================================== --- trunk/nuiton-utils/src/test/java/org/nuiton/util/decorator/MapPropertyHandlerTest.java (rev 0) +++ trunk/nuiton-utils/src/test/java/org/nuiton/util/decorator/MapPropertyHandlerTest.java 2011-07-31 13:25:21 UTC (rev 2155) @@ -0,0 +1,128 @@ +/* + * #%L + * Nuiton Utils :: Nuiton Utils + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2004 - 2011 CodeLutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ +package org.nuiton.util.decorator; + +import org.apache.commons.jxpath.JXPathIntrospector; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.junit.Assert; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +import java.util.Map; +import java.util.TreeMap; + +/** + * Tests the class {@link MapPropertyHandler}. + * + * @author tchemit <chemit@codelutin.com> + * @since 2.0.1 + */ +public class MapPropertyHandlerTest extends JXPathContextTester { + + + /** Logger */ + private static final Log log = + LogFactory.getLog(MapPropertyHandlerTest.class); + + private static final String TWO_ID = "two"; + + private static final String ONE_ID = "one"; + + @BeforeClass + public static void beforeClass() { + + // pour initialiser le JXPathContext + JXPathIntrospector.registerDynamicClass( + Map.class, + MapPropertyHandler.class + ); + } + + @Before + public void setUp() { + + Map<String, Boolean> map = new TreeMap<String, Boolean>(); + map.put(ONE_ID, true); + map.put(TWO_ID, false); + + if (log.isInfoEnabled()) { + log.info("init map : " + map); + } + newContext(map); + } + + @Test + public void testValues() throws Exception { + + Boolean value; + + value = (Boolean) getValue(".[@name='one']"); + Assert.assertNotNull(value); + Assert.assertTrue(value); + + value = (Boolean) getValue(".[@name='two']"); + Assert.assertNotNull(value); + Assert.assertFalse(value); + + value = (Boolean) getValue(".[@name='three']"); + Assert.assertNull(value); + } + + @Test + public void testKey() throws Exception { + + String key; + + key = (String) getValue(".[@name='key:one']"); + Assert.assertNotNull(key); + Assert.assertEquals(ONE_ID, key); + + key = (String) getValue(".[@name='key:two']"); + Assert.assertNotNull(key); + Assert.assertEquals(TWO_ID, key); + + key = (String) getValue(".[@name='key:fake']"); + Assert.assertNull(key); + } + + @Test + public void testValue() throws Exception { + + Boolean value; + + value = (Boolean) getValue(".[@name='value:true']"); + Assert.assertNotNull(value); + Assert.assertTrue(value); + + value = (Boolean) getValue(".[@name='value:false']"); + Assert.assertNotNull(value); + Assert.assertFalse(value); + + value = (Boolean) getValue(".[@name='value:fake']"); + Assert.assertNull(value); + } +} Property changes on: trunk/nuiton-utils/src/test/java/org/nuiton/util/decorator/MapPropertyHandlerTest.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Added: trunk/nuiton-utils/src/test/java/org/nuiton/util/decorator/MultiJXPathDecoratorTest.java =================================================================== --- trunk/nuiton-utils/src/test/java/org/nuiton/util/decorator/MultiJXPathDecoratorTest.java (rev 0) +++ trunk/nuiton-utils/src/test/java/org/nuiton/util/decorator/MultiJXPathDecoratorTest.java 2011-07-31 13:25:21 UTC (rev 2155) @@ -0,0 +1,254 @@ +/* + * #%L + * Nuiton Utils :: Nuiton Utils + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2004 - 2011 CodeLutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ +package org.nuiton.util.decorator; + +import org.junit.After; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +import static org.junit.Assert.assertEquals; + +/** + * @author tchemit <chemit@codelutin.com> + * @since 1.7.2 (was previously {@code jaxx.runtime.MultiJXPathDecoratorTest}). + */ +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 = DecoratorUtils.newMultiJXPathDecorator(null, "hello", "#"); + } + + @Test(expected = IllegalArgumentException.class) + public void testMissingRightBrace() throws Exception { + decorator = DecoratorUtils.newMultiJXPathDecorator(Object.class, "${haha", "#"); + } + + @Test(expected = IllegalArgumentException.class) + public void testMissingRightBrace2() throws Exception { + decorator = DecoratorUtils.newMultiJXPathDecorator(Object.class, "${haha${hum}", "#"); + } + + @Test + public void testNullBean() throws Exception { + decorator = DecoratorUtils.newMultiJXPathDecorator(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 = DecoratorUtils.newMultiJXPathDecorator(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 = DecoratorUtils.newMultiJXPathDecorator(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 = DecoratorUtils.newMultiJXPathDecorator(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 testDecoratorEspcapeCharacters() throws Exception { + + decorator = DecoratorUtils.newMultiJXPathDecorator(JXPathDecorator.class, "(${expression}$s)#${nbToken}$d", "#", " - "); + assertEquals("(%1$s) - %2$d", decorator.getExpression()); + assertTokens("expression", "nbToken"); + assertEquals(2, decorator.contexts.length); + expected = String.format(decorator.getExpression(), decorator.getExpression(), decorator.getNbToken()); + result = decorator.toString(decorator); + System.out.println("s=" + result); + assertEquals(expected, result); + + decorator = DecoratorUtils.newMultiJXPathDecorator(JXPathDecorator.class, "${nbToken}$d#(${expression}$s)", "#", " - "); + assertEquals("%1$d - (%2$s)", decorator.getExpression()); + assertTokens("nbToken", "expression"); + assertEquals(2, decorator.contexts.length); + expected = String.format(decorator.getExpression(), decorator.getNbToken(), decorator.getExpression()); + result = decorator.toString(decorator); + System.out.println("s=" + result); + assertEquals(expected, result); + + DecoratorProvider provider = new DecoratorProvider() { + + @Override + protected void loadDecorators() { + } + + }; + provider.registerMultiJXPathDecorator(MultiJXPathDecorator.class, "(${expression}$s)#${nbToken}$d", "#", " - "); + decorator = (MultiJXPathDecorator<?>) provider.getDecorator(MultiJXPathDecorator.class); + + assertEquals("(%1$s) - %2$d", decorator.getExpression()); + assertTokens("expression", "nbToken"); + assertEquals(2, decorator.contexts.length); + expected = String.format(decorator.getExpression(), decorator.getExpression(), decorator.getNbToken()); + result = decorator.toString(decorator); + System.out.println("s=" + result); + assertEquals(expected, result); + + } + + @Test + public void testMultiDecoratorWithMultiRef() throws Exception { + + decorator = DecoratorUtils.newMultiJXPathDecorator(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 %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 %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 testSort() throws Exception { + + List<Data> datas = Data.generate(10); + + MultiJXPathDecorator<Data> d = DecoratorUtils.newMultiJXPathDecorator(Data.class, "${pos}$d-${name}$s", "-"); + + List<Data> sortData = new ArrayList<Data>(datas); + DecoratorUtils.sort(d, sortData, 0); + for (int i = 0; i < datas.size(); i++) { + Data data = datas.get(i); + Data sData = sortData.get(i); + assertEquals(data, sData); + } + Collections.sort(datas, new Comparator<Data>() { + + @Override + public int compare(Data o1, Data o2) { + return o1.name.compareTo(o2.name); + } + }); + d.setContextIndex(1); + DecoratorUtils.sort(d, sortData, 1); + for (int i = 0; i < datas.size(); i++) { + Data data = datas.get(i); + Data sData = sortData.get(i); + assertEquals(data, sData); + } + } + + 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]); + } + } +} Property changes on: trunk/nuiton-utils/src/test/java/org/nuiton/util/decorator/MultiJXPathDecoratorTest.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Modified: trunk/nuiton-validator/src/license/THIRD-PARTY.properties =================================================================== --- trunk/nuiton-validator/src/license/THIRD-PARTY.properties 2011-07-19 16:46:06 UTC (rev 2154) +++ trunk/nuiton-validator/src/license/THIRD-PARTY.properties 2011-07-31 13:25:21 UTC (rev 2155) @@ -1,15 +1,20 @@ -# Generated by org.nuiton.license.plugin.AddThirdPartyMojo +# Generated by org.codehaus.mojo.license.AddThirdPartyMojo #------------------------------------------------------------------------------- # Already used licenses in project : # - BSD License # - Common Public License Version 1.0 # - Lesser General Public License (LGPL) v 3.0 +# - Lesser General Public License (LPGL) +# - Lesser General Public License (LPGL) v 2.1 +# - Lesser General Public License v2.1,Mozilla Public License 1.1 (MPL) # - The Apache Software License, Version 2.0 #------------------------------------------------------------------------------- # Please fill the missing licenses for dependencies : # # -#Wed Jan 26 12:51:06 CET 2011 +#Sun Jul 31 15:22:20 CEST 2011 +asm--asm--3.1--jar=http\://asm.ow2.org/license.html +asm--asm-commons--3.1--jar=http\://asm.ow2.org/license.html +asm--asm-tree--3.1--jar=http\://asm.ow2.org/license.html commons-primitives--commons-primitives--1.0--jar=The Apache Software License, Version 2.0 javassist--javassist--3.8.0.GA--jar=Lesser General Public License v2.1,Mozilla Public License 1.1 (MPL) -ognl--ognl--3.0--jar=The OpenSymphony Software License 1.1 \ No newline at end of file
participants (1)
-
tchemit@users.nuiton.org