Author: tchemit
Date: 2008-12-23 10:35:41 +0000 (Tue, 23 Dec 2008)
New Revision: 1091
Added:
lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/swing/DecoratorTableCellRenderer.java
lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/swing/I18nTableCellRenderer.java
Removed:
lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/swing/I18nTableCellHeaderRenderer.java
Modified:
lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/DefaultJAXXContext.java
lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/JXPathDecorator.java
lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/MultiJXPathDecorator.java
lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/swing/Utils.java
lutinjaxx/trunk/jaxx-core/src/test/java/jaxx/runtime/JXPathDecoratorTest.java
lutinjaxx/trunk/jaxx-core/src/test/java/jaxx/runtime/MultiJXPathDecoratorTest.java
Log:
- fix parent context search bug : if a nmae is given, use it.
- improve comparator in JXPathDecorator, no more redondant datas
- make works I18nCellRenderer when the position of column has changed
Modified: lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/DefaultJAXXContext.java
===================================================================
--- lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/DefaultJAXXContext.java 2008-12-23 10:31:56 UTC (rev 1090)
+++ lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/DefaultJAXXContext.java 2008-12-23 10:35:41 UTC (rev 1091)
@@ -50,7 +50,7 @@
}
public <T> void setContextValue(T o, String name) {
- if (PARENT_CONTEXT_ENTRY.accept2(o.getClass(), null)) {
+ if (name == null && PARENT_CONTEXT_ENTRY.accept2(o.getClass(), null)) {
setParentContext((JAXXContext) o);
return;
}
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-23 10:31:56 UTC (rev 1090)
+++ lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/JXPathDecorator.java 2008-12-23 10:35:41 UTC (rev 1091)
@@ -1,18 +1,16 @@
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.HashMap;
import java.util.List;
+import java.util.Map;
/**
* JXPath decorator based on {@link String#format(String, Object[])} method.
@@ -67,11 +65,55 @@
* @param datas the list of data to sort
* @param pos the index of context to used in decorator to obtain sorted property.
*/
- public static void sort(JXPathDecorator decorator, List<?> datas, int pos) {
- Collections.sort(datas, decorator.getComparator(pos));
+ public static <O> void sort(JXPathDecorator<O> decorator, List<O> datas, int pos) {
+ Comparator<O> c = decorator.getComparator(pos);
+ boolean cachedComparator = c instanceof JXPathComparator;
+ try {
+ if (cachedComparator) {
+ ((JXPathComparator<O>) c).init(decorator, datas);
+ }
+ Collections.sort(datas, c);
+ } finally {
+ if (cachedComparator) {
+ ((JXPathComparator) c).clear();
+ }
+ }
}
- protected static class Context implements Serializable {
+ 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;
+ this.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);
+ 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 = decorator.getTokenValue(jxcontext, expression);
+ valueCache.put(data, key);
+ }
+ }
+ }
+
+ public static class Context<O> implements java.io.Serializable {
+
/**
* expression to format using {@link String#format(String, Object[])}, all variables are compute
* using using the jxpath tokens.
@@ -81,7 +123,7 @@
/** list of jxpath tokens to apply on expression */
protected String[] tokens;
- protected transient Comparator comparator;
+ protected transient Comparator<O> comparator;
private static final long serialVersionUID = 1L;
@@ -94,62 +136,15 @@
return tokens[0];
}
- public Comparator getComparator(JXPathDecorator decorator, int pos) {
+ public Comparator<O> getComparator(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;
+ comparator = new JXPathComparator<O>(tokens[pos]);
}
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);
+ public void setComparator(Comparator<O> comparator) {
+ this.comparator = comparator;
}
@Override
@@ -159,7 +154,7 @@
}
/** the computed context of the decorator */
- protected Context context;
+ protected Context<O> context;
/** nb jxpath tokens to compute */
protected int nbToken;
@@ -167,9 +162,6 @@
/** 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;
@@ -177,11 +169,17 @@
JXPathContext jxcontext = JXPathContext.newContext(bean);
Object[] args = new Object[nbToken];
for (int i = 0; i < nbToken; i++) {
- args[i] = jxcontext.getValue(context.tokens[i]);
+ args[i] = getTokenValue(jxcontext, context.tokens[i]);
}
return String.format(context.expression, args);
}
+ @SuppressWarnings({"unchecked"})
+ protected Comparable<Comparable> getTokenValue(JXPathContext jxcontext, String token) {
+ // assume all values are comparable
+ return (Comparable<Comparable>) jxcontext.getValue(token);
+ }
+
public String getProperty(int pos) {
return getTokens()[pos];
}
@@ -207,14 +205,7 @@
return super.toString() + "<" + context + ">";
}
- public PropertyDescriptor[] getDescriptors() {
- if (descriptors == null) {
- descriptors = PropertyUtils.getPropertyDescriptors(internalClass);
- }
- return descriptors;
- }
-
- public void setContext(Context context) {
+ public void setContext(Context<O> context) {
this.context = context;
this.nbToken = context.tokens.length;
// always reset comparator
@@ -224,11 +215,11 @@
}
}
- protected JXPathDecorator(Class<O> internalClass, String expression, boolean creatContext) throws IllegalArgumentException, NullPointerException {
+ public JXPathDecorator(Class<O> internalClass, String expression, boolean creatContext) throws IllegalArgumentException, NullPointerException {
super(internalClass);
this.initialExpression = expression;
if (creatContext) {
- setContext(createInitialContext(expression));
+ setContext(JXPathDecorator.<O>createInitialContext(expression));
if (log.isDebugEnabled()) {
log.debug(expression + " --> " + this.context);
}
@@ -238,10 +229,10 @@
@SuppressWarnings({"unchecked"})
protected Comparator<O> getComparator(int pos) {
ensureTokenIndex(this, pos);
- return context.getComparator(this, pos);
+ return context.getComparator(pos);
}
- protected static Context createInitialContext(String expression) {
+ public static <O> Context<O> createInitialContext(String expression) {
List<String> lTokens = new ArrayList<String>();
StringBuilder buffer = new StringBuilder();
int size = expression.length();
@@ -271,7 +262,7 @@
// suffix after end jxpath (or all expression if no jxpath)
buffer.append(expression.substring(end + 1));
}
- return new Context(buffer.toString(), lTokens.toArray(new String[lTokens.size()]));
+ return new Context<O>(buffer.toString(), lTokens.toArray(new String[lTokens.size()]));
}
protected static void ensureTokenIndex(JXPathDecorator decorator, int pos) {
Modified: lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/MultiJXPathDecorator.java
===================================================================
--- lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/MultiJXPathDecorator.java 2008-12-23 10:31:56 UTC (rev 1090)
+++ lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/MultiJXPathDecorator.java 2008-12-23 10:35:41 UTC (rev 1091)
@@ -35,19 +35,19 @@
String separatorReplacement)
throws IllegalArgumentException, NullPointerException {
- Context[] contexts = createInitialContexts(expression, separator, separatorReplacement);
+ Context<O>[] contexts = createInitialContexts(expression, separator, separatorReplacement);
return new MultiJXPathDecorator<O>(internalClass, expression, separator, separatorReplacement, contexts);
}
- protected Context[] contexts;
+ protected Context<O>[] contexts;
protected String separator;
protected String separatorReplacement;
- protected MultiJXPathDecorator(Class<O> internalClass, String expression,
- String separator, String separatorReplacement,
- Context[] contexts) throws IllegalArgumentException, NullPointerException {
+ public MultiJXPathDecorator(Class<O> internalClass, String expression,
+ String separator, String separatorReplacement,
+ Context<O>[] contexts) throws IllegalArgumentException, NullPointerException {
super(internalClass, expression, false);
this.separator = separator;
this.separatorReplacement = separatorReplacement;
@@ -80,13 +80,16 @@
@Override
protected Comparator<O> getComparator(int pos) {
ensureContextIndex(this, pos);
- return contexts[pos].getComparator(this, 0);
+ Context<O> context1 = contexts[pos];
+ return context1.getComparator(0);
}
- protected static Context[] createInitialContexts(String expression, String separator, String separatorReplacement) {
+ public static <O> Context<O>[] createInitialContexts(String expression, String separator, String separatorReplacement) {
int sep = expression.indexOf(separator);
if (sep == -1) {
- return new Context[]{createInitialContext(expression)};
+ Context<O>[] result = MultiJXPathDecorator.newInstance(1);
+ result[0] = createInitialContext(expression);
+ return result;
}
List<String> tokens = new ArrayList<String>();
@@ -96,7 +99,7 @@
}
int nbTokens = tokens.size();
- Context[] contexts = new Context[nbTokens];
+ Context<O>[] contexts = newInstance(nbTokens);
for (int i = 0; i < nbTokens; i++) {
StringBuilder buffer = new StringBuilder(expression.length());
for (int j = 0; j < nbTokens; j++) {
@@ -116,4 +119,10 @@
}
}
+ @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];
+ }
+
}
\ No newline at end of file
Copied: lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/swing/DecoratorTableCellRenderer.java (from rev 1060, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/swing/I18nTableCellHeaderRenderer.java)
===================================================================
--- lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/swing/DecoratorTableCellRenderer.java (rev 0)
+++ lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/swing/DecoratorTableCellRenderer.java 2008-12-23 10:35:41 UTC (rev 1091)
@@ -0,0 +1,33 @@
+package jaxx.runtime.swing;
+
+import jaxx.runtime.Decorator;
+
+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 DecoratorTableCellRenderer implements TableCellRenderer {
+
+ /** the delegate cell renderer */
+ protected TableCellRenderer delegate;
+
+ protected Decorator decorator;
+
+ public DecoratorTableCellRenderer(TableCellRenderer delegate, Decorator decorator) {
+ this.delegate = delegate;
+ this.decorator = decorator;
+ }
+
+ public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasfocus, int row, int column) {
+ if (value != null) {
+ value = decorator.toString(value);
+ }
+ return delegate.getTableCellRendererComponent(table, value, isSelected, hasfocus, row, column);
+ }
+}
\ No newline at end of file
Property changes on: lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/swing/DecoratorTableCellRenderer.java
___________________________________________________________________
Name: svn:mergeinfo
+
Deleted: lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/swing/I18nTableCellHeaderRenderer.java
===================================================================
--- lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/swing/I18nTableCellHeaderRenderer.java 2008-12-23 10:31:56 UTC (rev 1090)
+++ lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/swing/I18nTableCellHeaderRenderer.java 2008-12-23 10:35:41 UTC (rev 1091)
@@ -1,38 +0,0 @@
-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;
- }
-}
Copied: lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/swing/I18nTableCellRenderer.java (from rev 1060, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/swing/I18nTableCellHeaderRenderer.java)
===================================================================
--- lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/swing/I18nTableCellRenderer.java (rev 0)
+++ lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/swing/I18nTableCellRenderer.java 2008-12-23 10:35:41 UTC (rev 1091)
@@ -0,0 +1,42 @@
+package jaxx.runtime.swing;
+
+import static org.codelutin.i18n.I18n._;
+
+import javax.swing.JTable;
+import javax.swing.table.TableCellRenderer;
+import javax.swing.table.TableColumn;
+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 I18nTableCellRenderer implements TableCellRenderer {
+
+ /** the libelles to display */
+ protected final String[] keys;
+
+ /** the delegate cell renderer */
+ protected TableCellRenderer delegate;
+
+ public I18nTableCellRenderer(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);
+ }
+ TableColumn col = table.getColumn(table.getColumnName(column));
+ value = _(keys[col.getModelIndex()]);
+ return delegate.getTableCellRendererComponent(table, value, isSelected, hasfocus, row, column);
+
+ /*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/Utils.java
===================================================================
--- lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/swing/Utils.java 2008-12-23 10:31:56 UTC (rev 1090)
+++ lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/swing/Utils.java 2008-12-23 10:35:41 UTC (rev 1091)
@@ -7,7 +7,11 @@
import javax.swing.DefaultComboBoxModel;
import javax.swing.ImageIcon;
import javax.swing.JComboBox;
+import javax.swing.JTable;
import javax.swing.SwingUtilities;
+import javax.swing.table.TableCellEditor;
+import javax.swing.table.TableCellRenderer;
+import javax.swing.table.TableColumn;
import javax.swing.text.AbstractDocument;
import javax.swing.text.JTextComponent;
import java.lang.reflect.Field;
@@ -104,4 +108,22 @@
model.setSelectedItem(select);
}
+ public static void fixTableColumnWidth(JTable table, int columnIndex, int width) {
+ TableColumn column = table.getColumnModel().getColumn(columnIndex);
+ column.setMaxWidth(width);
+ column.setMinWidth(width);
+ column.setWidth(width);
+ column.setPreferredWidth(width);
+ }
+
+ public static void setTableColumnEditor(JTable table, int columnIndex, TableCellEditor editor) {
+ TableColumn column = table.getColumnModel().getColumn(columnIndex);
+ column.setCellEditor(editor);
+ }
+
+ public static void setTableColumnRenderer(JTable table, int columnIndex, TableCellRenderer editor) {
+ TableColumn column = table.getColumnModel().getColumn(columnIndex);
+ column.setCellRenderer(editor);
+ }
+
}
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-23 10:31:56 UTC (rev 1090)
+++ lutinjaxx/trunk/jaxx-core/src/test/java/jaxx/runtime/JXPathDecoratorTest.java 2008-12-23 10:35:41 UTC (rev 1091)
@@ -1,9 +1,15 @@
package jaxx.runtime;
+import jaxx.runtime.JXPathDecorator.Context;
import org.junit.After;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
/** @author chemit */
public class JXPathDecoratorTest {
@@ -76,6 +82,67 @@
assertDecoratorInternal();
}
+ public static 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 + '\'' + '}';
+ }
+ }
+
+ @Test
+ public void testSort() throws Exception {
+
+ List<Data> datas = Data.generate(10);
+ JXPathDecorator<Data> decorator = JXPathDecorator.newDecorator(Data.class, "${pos}$d ${name}$s");
+
+ List<Data> sortData = new ArrayList<Data>(datas);
+ JXPathDecorator.sort(decorator, 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);
+ }
+ });
+ Context<Data> context = decorator.context;
+ context.setComparator(null);
+ JXPathDecorator.sort(decorator, 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());
Modified: lutinjaxx/trunk/jaxx-core/src/test/java/jaxx/runtime/MultiJXPathDecoratorTest.java
===================================================================
--- lutinjaxx/trunk/jaxx-core/src/test/java/jaxx/runtime/MultiJXPathDecoratorTest.java 2008-12-23 10:31:56 UTC (rev 1090)
+++ lutinjaxx/trunk/jaxx-core/src/test/java/jaxx/runtime/MultiJXPathDecoratorTest.java 2008-12-23 10:35:41 UTC (rev 1091)
@@ -1,9 +1,15 @@
package jaxx.runtime;
+import jaxx.runtime.JXPathDecoratorTest.Data;
import org.junit.After;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
/** @author chemit */
public class MultiJXPathDecoratorTest {
@@ -128,6 +134,35 @@
assertEquals(expected, result);
}
+ @Test
+ public void testSort() throws Exception {
+
+ List<Data> datas = Data.generate(10);
+
+ MultiJXPathDecorator<Data> decorator = MultiJXPathDecorator.newDecorator(Data.class, "${pos}$d-${name}$s", "-");
+
+ List<Data> sortData = new ArrayList<Data>(datas);
+ JXPathDecorator.sort(decorator, 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);
+ }
+ });
+ decorator.setContextIndex(1);
+ JXPathDecorator.sort(decorator, 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());