    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}