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
015package org.apache.tapestry5.internal.grid;
016
017import java.util.Collection;
018import java.util.Collections;
019import java.util.Comparator;
020import java.util.List;
021
022import org.apache.tapestry5.PropertyConduit;
023import org.apache.tapestry5.grid.ColumnSort;
024import org.apache.tapestry5.grid.GridDataSource;
025import org.apache.tapestry5.grid.SortConstraint;
026import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
027
028@SuppressWarnings("all")
029public 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}