    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.beanmodel.PropertyConduit;
    023import org.apache.tapestry5.commons.util.CollectionFactory;
    024import org.apache.tapestry5.grid.ColumnSort;
    025import org.apache.tapestry5.grid.GridDataSource;
    026import org.apache.tapestry5.grid.SortConstraint;
    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    @Override
    040    public boolean isEmpty()
    041    {
    042        return list.isEmpty();
    043    }
    044
    045    public int getAvailableRows()
    046    {
    047        return list.size();
    048    }
    049
    050    public void prepare(int startIndex, int endIndex, List<SortConstraint> sortConstraints)
    051    {
    052        for (SortConstraint constraint : sortConstraints)
    053        {
    054            final ColumnSort sort = constraint.getColumnSort();
    055
    056            if (sort == ColumnSort.UNSORTED)
    057                continue;
    058
    059            final PropertyConduit conduit = constraint.getPropertyModel().getConduit();
    060
    061            final Comparator valueComparator = new Comparator<Comparable>()
    062            {
    063                public int compare(Comparable o1, Comparable o2)
    064                {
    065                    // Simplify comparison, and handle case where both are nulls.
    066
    067                    if (o1 == o2)
    068                        return 0;
    069
    070                    if (o2 == null)
    071                        return 1;
    072
    073                    if (o1 == null)
    074                        return -1;
    075
    076                    return o1.compareTo(o2);
    077                }
    078            };
    079
    080            final Comparator rowComparator = new Comparator()
    081            {
    082                public int compare(Object row1, Object row2)
    083                {
    084                    Comparable value1 = (Comparable) conduit.get(row1);
    085                    Comparable value2 = (Comparable) conduit.get(row2);
    086
    087                    return valueComparator.compare(value1, value2);
    088                }
    089            };
    090
    091            final Comparator reverseComparator = new Comparator()
    092            {
    093                public int compare(Object o1, Object o2)
    094                {
    095                    int modifier = sort == ColumnSort.ASCENDING ? 1 : -1;
    096
    097                    return modifier * rowComparator.compare(o1, o2);
    098                }
    099            };
    100
    101            // We can freely sort this list because its just a copy.
    102
    103            Collections.sort(list, reverseComparator);
    104        }
    105    }
    106
    107    /**
    108     * Returns the type of the first element in the list, or null if the list is empty.
    109     */
    110    public Class getRowType()
    111    {
    112        return list.isEmpty() ? null : list.get(0).getClass();
    113    }
    114
    115    public Object getRowValue(int index)
    116    {
    117        return list.get(index);
    118    }
    119
    120}