You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by ar...@apache.org on 2010/12/28 21:23:43 UTC
svn commit: r1053424 - in /myfaces/trinidad/trunk:
trinidad-api/src/main/java/org/apache/myfaces/trinidad/model/SortableModel.java
trinidad-api/src/test/clirr/clirr-runner.txt
trinidad-examples/trinidad-demo/src/main/webapp/WEB-INF/faces-config.xml
Author: arobinson74
Date: Tue Dec 28 20:23:43 2010
New Revision: 1053424
URL: http://svn.apache.org/viewvc?rev=1053424&view=rev
Log:
TRINIDAD-1965 - improve sortable model API to support case insensitive sorting
Modified:
myfaces/trinidad/trunk/trinidad-api/src/main/java/org/apache/myfaces/trinidad/model/SortableModel.java
myfaces/trinidad/trunk/trinidad-api/src/test/clirr/clirr-runner.txt
myfaces/trinidad/trunk/trinidad-examples/trinidad-demo/src/main/webapp/WEB-INF/faces-config.xml
Modified: myfaces/trinidad/trunk/trinidad-api/src/main/java/org/apache/myfaces/trinidad/model/SortableModel.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/trunk/trinidad-api/src/main/java/org/apache/myfaces/trinidad/model/SortableModel.java?rev=1053424&r1=1053423&r2=1053424&view=diff
==============================================================================
--- myfaces/trinidad/trunk/trinidad-api/src/main/java/org/apache/myfaces/trinidad/model/SortableModel.java (original)
+++ myfaces/trinidad/trunk/trinidad-api/src/main/java/org/apache/myfaces/trinidad/model/SortableModel.java Tue Dec 28 20:23:43 2010
@@ -6,9 +6,9 @@
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@@ -23,8 +23,10 @@ import java.text.Collator;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
+import java.util.HashMap;
import java.util.List;
import java.util.Locale;
+import java.util.Map;
import javax.el.ELContext;
import javax.el.ELResolver;
@@ -48,6 +50,60 @@ import org.apache.myfaces.trinidad.loggi
public class SortableModel extends CollectionModel
{
/**
+ * This class provides an enumeration to work with the integer values of the
+ * {@link Collator} strength values.
+ */
+ public enum Strength
+ {
+ /** @see Collator#IDENTICAL */
+ IDENTICAL(Collator.IDENTICAL),
+ /** @see Collator#PRIMARY */
+ PRIMARY(Collator.PRIMARY),
+ /** @see Collator#SECONDARY */
+ SECONDARY(Collator.SECONDARY),
+ /** @see Collator#TERTIARY */
+ TERTIARY(Collator.TERTIARY);
+
+ private Strength(int strength)
+ {
+ _strength = strength;
+ }
+
+ public int getIntValue()
+ {
+ return _strength;
+ }
+
+ private final int _strength;
+ }
+
+ /**
+ * This class provides an enumeration to work with the integer values of the
+ * {@link Collator} decomposition values.
+ */
+ public enum Decomposition
+ {
+ /** @see Collator#PRIMARY */
+ NO_DECOMPOSITION(Collator.NO_DECOMPOSITION),
+ /** @see Collator#SECONDARY */
+ CANONICAL_DECOMPOSITION(Collator.CANONICAL_DECOMPOSITION),
+ /** @see Collator#TERTIARY */
+ FULL_DECOMPOSITION(Collator.FULL_DECOMPOSITION);
+
+ private Decomposition(int decomposition)
+ {
+ _decomposition = decomposition;
+ }
+
+ public int getIntValue()
+ {
+ return _decomposition;
+ }
+
+ private final int _decomposition;
+ }
+
+ /**
* Create a new SortableModel from the given instance.
* @param model This will be converted into a {@link DataModel}
* @see #setWrappedData
@@ -204,7 +260,7 @@ public class SortableModel extends Colle
//simple property -> resolve value directly
if (!property.contains( "." ))
return resolver.getValue(context, base, property );
-
+
int index = property.indexOf( '.' );
Object newBase = resolver.getValue(context, base, property.substring( 0, index ) );
@@ -244,6 +300,97 @@ public class SortableModel extends Colle
}
}
+ /**
+ * Get the comparator associated with the given property.
+ *
+ * @param propertyName the property
+ * @return the comparator or null if one has not been set
+ */
+ public Comparator getComparator(
+ String propertyName)
+ {
+ return _propertyComparators == null ?
+ null :
+ _propertyComparators.get(propertyName);
+ }
+
+ /**
+ * Set a custom comparator to use to sort the given property name.
+ *
+ * @param propertyName the property with which to associate the comparator
+ * @param comparator the comparator to use, or null to remove one
+ */
+ public void setComparator(
+ String propertyName,
+ Comparator comparator)
+ {
+ assert propertyName != null : "Property name may not be null";
+
+ if (comparator == null && _propertyComparators != null)
+ {
+ _propertyComparators.remove(propertyName);
+ if (_propertyComparators.isEmpty())
+ {
+ _propertyComparators = null;
+ }
+ }
+ else if (comparator != null)
+ {
+ if (_propertyComparators == null)
+ {
+ _propertyComparators = new HashMap<String, Comparator>();
+ }
+ _propertyComparators.put(propertyName, comparator);
+ }
+
+ if (_sortCriterion != null && propertyName.equals(_sortCriterion.getProperty()))
+ {
+ _sort(_sortCriterion.getProperty(), _sortCriterion.isAscending());
+ }
+ }
+
+ /**
+ * Convenience method to set a compatator for a property using a {@link Collator} setup with
+ * the given strength and decomposition values.
+ *
+ * @param propertyName the property
+ * @param collatorStrength the stregth to use or null to leave as the default for the
+ * default locale
+ * @param collatorDecomposition the decomposition to use or null to leave as the default for the
+ * default locale
+ * @see #setComparator(String, Comparator)
+ */
+ public void setCollator(
+ String propertyName,
+ Strength collatorStrength,
+ Decomposition collatorDecomposition)
+ {
+ Locale locale = null;
+
+ RequestContext reqCtx = RequestContext.getCurrentInstance();
+ if (reqCtx != null)
+ {
+ FacesContext facesContext = FacesContext.getCurrentInstance();
+ if (facesContext != null)
+ {
+ locale = _getLocale(reqCtx, facesContext);
+ }
+ }
+
+ Collator collator = locale == null ? Collator.getInstance() : Collator.getInstance(locale);
+ if (collatorDecomposition != null)
+ {
+ collator.setDecomposition(collatorDecomposition.getIntValue());
+ }
+
+ if (collatorStrength != null)
+ {
+ collator.setStrength(collatorStrength.getIntValue());
+ }
+
+ setComparator(propertyName, collator);
+ }
+
@Override
public String toString()
{
@@ -355,7 +502,7 @@ public class SortableModel extends Colle
}
-
+
private static final class IntList extends ArrayList<Integer>
{
public IntList(int size)
@@ -377,7 +524,11 @@ public class SortableModel extends Colle
private final class Comp implements Comparator<Integer>
{
- public Comp(ELResolver resolver, ELContext context, Locale locale, String property)
+ public Comp(
+ ELResolver resolver,
+ ELContext context,
+ Locale locale,
+ String property)
{
_resolver = resolver;
_context = context;
@@ -395,7 +546,9 @@ public class SortableModel extends Colle
}
@SuppressWarnings("unchecked")
- public int compare(Integer o1, Integer o2)
+ public int compare(
+ Integer o1,
+ Integer o2)
{
int index1 = o1.intValue();
int index2 = o2.intValue();
@@ -414,30 +567,40 @@ public class SortableModel extends Colle
if (value2 == null)
return 1;
- // bug 4545164. Sometimes, isSortable returns true
- // even if the underlying object is not a Comparable.
- // This happens if the object at rowIndex zero is null.
- // So test before we cast:
- if (value1 instanceof Comparable)
+ Comparator comparator = getComparator(_prop);
+ if (comparator == null)
{
- if ((value1 instanceof String) && (value2 instanceof String))
+ // bug 4545164. Sometimes, isSortable returns true
+ // even if the underlying object is not a Comparable.
+ // This happens if the object at rowIndex zero is null.
+ // So test before we cast:
+ if (value1 instanceof Comparable)
{
- return compare((String) value1, (String) value2);
+ if ((value1 instanceof String) && (value2 instanceof String))
+ {
+ return _compare((String) value1, (String) value2);
+ }
+ else
+ {
+ return ((Comparable<Object>) value1).compareTo(value2);
+ }
}
- else
+ else
{
- return ((Comparable<Object>) value1).compareTo(value2);
+ // if the object is not a Comparable, then
+ // the best we can do is string comparison:
+ return _compare(value1.toString(), value2.toString());
}
}
else
{
- // if the object is not a Comparable, then
- // the best we can do is string comparison:
- return compare(value1.toString(), value2.toString());
+ return comparator.compare(value1, value2);
}
}
- private int compare(String s1, String s2)
+ private int _compare(
+ String s1,
+ String s2)
{
if (_collator != null)
{
@@ -480,7 +643,7 @@ public class SortableModel extends Colle
{
_resolver = resolver;
}
-
+
@Override
public ELResolver getELResolver()
{
@@ -502,7 +665,7 @@ public class SortableModel extends Colle
// to an ELResolver, no VariableMapper is needed
return null;
}
-
+
private final ELResolver _resolver;
}
@@ -522,7 +685,7 @@ public class SortableModel extends Colle
if (context != null)
return context.getELContext();
- return new ELContextImpl(resolver);
+ return new ELContextImpl(resolver);
}
static private ELResolver _getELResolver(FacesContext context)
@@ -537,10 +700,10 @@ public class SortableModel extends Colle
ApplicationFactory factory = (ApplicationFactory)
FactoryFinder.getFactory(FactoryFinder.APPLICATION_FACTORY);
return factory.getApplication().getELResolver();
-
+
}
- static private Locale _getLocale(RequestContext requestContext, FacesContext facesContext)
+ static private Locale _getLocale(RequestContext requestContext, FacesContext facesContext)
{
if (requestContext != null)
return requestContext.getFormattingLocale();
@@ -556,6 +719,8 @@ public class SortableModel extends Colle
private DataModel _model = null;
private Object _wrappedData = null;
+ private Map<String, Comparator> _propertyComparators;
+
private IntList _sortedIndicesList = null, // from baseIndex to sortedIndex
_baseIndicesList = null; // from sortedIndex to baseIndex
Modified: myfaces/trinidad/trunk/trinidad-api/src/test/clirr/clirr-runner.txt
URL: http://svn.apache.org/viewvc/myfaces/trinidad/trunk/trinidad-api/src/test/clirr/clirr-runner.txt?rev=1053424&r1=1053423&r2=1053424&view=diff
==============================================================================
--- myfaces/trinidad/trunk/trinidad-api/src/test/clirr/clirr-runner.txt (original)
+++ myfaces/trinidad/trunk/trinidad-api/src/test/clirr/clirr-runner.txt Tue Dec 28 20:23:43 2010
@@ -1317,6 +1317,11 @@ INFO: 4000: org.apache.myfaces.trinidad.
INFO: 8000: org.apache.myfaces.trinidad.model.RowKeyPropertyModel: Class org.apache.myfaces.trinidad.model.RowKeyPropertyModel added
INFO: 8000: org.apache.myfaces.trinidad.model.RowKeyPropertyTreeModel: Class org.apache.myfaces.trinidad.model.RowKeyPropertyTreeModel added
INFO: 4000: org.apache.myfaces.trinidad.model.SortableModel: Added java.lang.Iterable to the set of implemented interfaces
+INFO: 7011: org.apache.myfaces.trinidad.model.SortableModel: Method 'public java.util.Comparator getComparator(java.lang.String)' has been added
+INFO: 7011: org.apache.myfaces.trinidad.model.SortableModel: Method 'public void setCollator(java.lang.String, org.apache.myfaces.trinidad.model.SortableModel$Strength, org.apache.myfaces.trinidad.model.SortableModel$Decomposition)' has been added
+INFO: 7011: org.apache.myfaces.trinidad.model.SortableModel: Method 'public void setComparator(java.lang.String, java.util.Comparator)' has been added
+INFO: 8000: org.apache.myfaces.trinidad.model.SortableModel$Decomposition: Class org.apache.myfaces.trinidad.model.SortableModel$Decomposition added
+INFO: 8000: org.apache.myfaces.trinidad.model.SortableModel$Strength: Class org.apache.myfaces.trinidad.model.SortableModel$Strength added
INFO: 4000: org.apache.myfaces.trinidad.model.TreeModel: Added java.lang.Iterable to the set of implemented interfaces
INFO: 4000: org.apache.myfaces.trinidad.model.ViewIdPropertyMenuModel: Added java.lang.Iterable to the set of implemented interfaces
INFO: 4000: org.apache.myfaces.trinidad.model.XMLMenuModel: Added java.lang.Iterable to the set of implemented interfaces
Modified: myfaces/trinidad/trunk/trinidad-examples/trinidad-demo/src/main/webapp/WEB-INF/faces-config.xml
URL: http://svn.apache.org/viewvc/myfaces/trinidad/trunk/trinidad-examples/trinidad-demo/src/main/webapp/WEB-INF/faces-config.xml?rev=1053424&r1=1053423&r2=1053424&view=diff
==============================================================================
--- myfaces/trinidad/trunk/trinidad-examples/trinidad-demo/src/main/webapp/WEB-INF/faces-config.xml (original)
+++ myfaces/trinidad/trunk/trinidad-examples/trinidad-demo/src/main/webapp/WEB-INF/faces-config.xml Tue Dec 28 20:23:43 2010
@@ -150,7 +150,7 @@
request
</managed-bean-scope>
</managed-bean>
-
+
<managed-bean>
<managed-bean-name>dateRestrictionValidator</managed-bean-name>
<managed-bean-class>
@@ -231,7 +231,7 @@
<managed-bean-scope>
session
</managed-bean-scope>
- </managed-bean>
+ </managed-bean>
<managed-bean>
<managed-bean-name>messages</managed-bean-name>
@@ -932,6 +932,7 @@
<value>table_selection.jspx</value>
<value>table_dynamic.jspx</value>
<value>table_nested.jspx</value>
+ <value>table_sorting.jspx</value>
<value>tree.jspx</value>
<value>treeTable.jspx</value>
<value>treeTable_selection.jspx</value>
@@ -2561,6 +2562,12 @@
</navigation-case>
<navigation-case>
+ <from-outcome>guide.table_sorting</from-outcome>
+ <to-view-id>/components/table_sorting.jspx</to-view-id>
+ <redirect/>
+ </navigation-case>
+
+ <navigation-case>
<from-outcome>guide.panelTip</from-outcome>
<to-view-id>/components/panelTip.jspx</to-view-id>
<redirect/>
@@ -2937,6 +2944,12 @@
</managed-bean>
<managed-bean>
+ <managed-bean-name>sortableTable</managed-bean-name>
+ <managed-bean-class>org.apache.myfaces.trinidaddemo.table.SortableModelBean</managed-bean-class>
+ <managed-bean-scope>session</managed-bean-scope>
+ </managed-bean>
+
+ <managed-bean>
<managed-bean-name>periodicTable</managed-bean-name>
<managed-bean-class>
org.apache.myfaces.trinidaddemo.table.TableBuilder