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}