001    // Copyright 2007, 2008, 2010 The Apache Software Foundation
002    //
003    // Licensed under the Apache License, Version 2.0 (the "License");
004    // you may not use this file except in compliance with the License.
005    // You may obtain a copy of the License at
006    //
007    // http://www.apache.org/licenses/LICENSE-2.0
008    //
009    // Unless required by applicable law or agreed to in writing, software
010    // distributed under the License is distributed on an "AS IS" BASIS,
011    // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012    // See the License for the specific language governing permissions and
013    // limitations under the License.
014    
015    package org.apache.tapestry5.internal.grid;
016    
017    import java.util.Collection;
018    import java.util.Collections;
019    import java.util.Comparator;
020    import java.util.List;
021    
022    import org.apache.tapestry5.PropertyConduit;
023    import org.apache.tapestry5.grid.ColumnSort;
024    import org.apache.tapestry5.grid.GridDataSource;
025    import org.apache.tapestry5.grid.SortConstraint;
026    import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
027    
028    @SuppressWarnings("all")
029    public class CollectionGridDataSource implements GridDataSource
030    {
031        private final List list;
032    
033        public CollectionGridDataSource(final Collection collection)
034        {
035            assert collection != null;
036            list = CollectionFactory.newList(collection);
037        }
038    
039        public int getAvailableRows()
040        {
041            return list.size();
042        }
043    
044        public void prepare(int startIndex, int endIndex, List<SortConstraint> sortConstraints)
045        {
046            for (SortConstraint constraint : sortConstraints)
047            {
048                final ColumnSort sort = constraint.getColumnSort();
049    
050                if (sort == ColumnSort.UNSORTED)
051                    continue;
052    
053                final PropertyConduit conduit = constraint.getPropertyModel().getConduit();
054    
055                final Comparator valueComparator = new Comparator<Comparable>()
056                {
057                    public int compare(Comparable o1, Comparable o2)
058                    {
059                        // Simplify comparison, and handle case where both are nulls.
060    
061                        if (o1 == o2)
062                            return 0;
063    
064                        if (o2 == null)
065                            return 1;
066    
067                        if (o1 == null)
068                            return -1;
069    
070                        return o1.compareTo(o2);
071                    }
072                };
073    
074                final Comparator rowComparator = new Comparator()
075                {
076                    public int compare(Object row1, Object row2)
077                    {
078                        Comparable value1 = (Comparable) conduit.get(row1);
079                        Comparable value2 = (Comparable) conduit.get(row2);
080    
081                        return valueComparator.compare(value1, value2);
082                    }
083                };
084    
085                final Comparator reverseComparator = new Comparator()
086                {
087                    public int compare(Object o1, Object o2)
088                    {
089                        int modifier = sort == ColumnSort.ASCENDING ? 1 : -1;
090    
091                        return modifier * rowComparator.compare(o1, o2);
092                    }
093                };
094    
095                // We can freely sort this list because its just a copy.
096    
097                Collections.sort(list, reverseComparator);
098            }
099        }
100    
101        /**
102         * Returns the type of the first element in the list, or null if the list is empty.
103         */
104        public Class getRowType()
105        {
106            return list.isEmpty() ? null : list.get(0).getClass();
107        }
108    
109        public Object getRowValue(int index)
110        {
111            return list.get(index);
112        }
113    
114    }