001/* 
002 * (C) Copyright 2006-2011 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 *
016 * Contributors:
017 *     Florent Guillaume
018 */
019package org.nuxeo.ecm.core.opencmis.impl.util;
020
021import java.math.BigInteger;
022import java.util.Collections;
023import java.util.List;
024
025/**
026 * Utilities around lists.
027 */
028public class ListUtils {
029
030    private ListUtils() {
031        // utility class
032    }
033
034    /**
035     * Returns a batched version of the list, according to the passed parameters.
036     *
037     * @param list the list
038     * @param maxItems the maximum number of items, or {@code null} for the default
039     * @param skipCount the skip count
040     * @param defaultMax the default maximum number of items if {@code maxItems} is {@code null}
041     * @return the batched list, which may be a sublist per {@link List#subList}
042     */
043    public static <T> List<T> batchList(List<T> list, BigInteger maxItems, BigInteger skipCount, int defaultMax) {
044        return getBatchedList(list, maxItems, skipCount, defaultMax).getList();
045    }
046
047    /**
048     * Returns a batched version of the list, according to the passed parameters.
049     *
050     * @param list the list
051     * @param maxItems the maximum number of items, or {@code null} for the default
052     * @param skipCount the skip count
053     * @param defaultMax the default maximum number of items if {@code maxItems} is {@code null}
054     * @return the batched list, which may be a sublist per {@link List#subList}
055     */
056    public static <T> BatchedList<T> getBatchedList(List<T> list, BigInteger maxItems, BigInteger skipCount,
057            int defaultMax) {
058        int skip = skipCount == null ? 0 : skipCount.intValue();
059        if (skip < 0) {
060            skip = 0;
061        }
062        int max = maxItems == null ? -1 : maxItems.intValue();
063        if (max < 0) {
064            max = defaultMax;
065        }
066        BatchedList<T> res = new BatchedList<T>();
067        res.setNumItems(list.size());
068        if (skip >= list.size()) {
069            res.setHasMoreItems(false);
070            res.setList(Collections.<T> emptyList());
071            return res;
072        }
073        if (max > list.size() - skip) {
074            max = list.size() - skip;
075        }
076        boolean hasMoreItems = max < list.size() - skip;
077        if (skip > 0 || hasMoreItems) {
078            list = list.subList(skip, skip + max);
079        }
080        res.setHasMoreItems(hasMoreItems);
081        res.setList(list);
082        return res;
083    }
084
085    /**
086     * A holder for a sublist of a list, a flag indicating if there were more elements after the included sublist, and
087     * the total number of items if there had been no batching.
088     *
089     * @param <T> the type of the list elements
090     */
091    public static class BatchedList<T> {
092
093        public List<T> list;
094
095        public boolean hasMoreItems = false;
096
097        public int numItems;
098
099        public List<T> getList() {
100            return list;
101        }
102
103        public void setList(List<T> list) {
104            this.list = list;
105        }
106
107        public Boolean getHasMoreItems() {
108            return Boolean.valueOf(hasMoreItems);
109        }
110
111        public void setHasMoreItems(boolean hasMoreItems) {
112            this.hasMoreItems = hasMoreItems;
113        }
114
115        public BigInteger getNumItems() {
116            return BigInteger.valueOf(numItems);
117        }
118
119        public void setNumItems(int numItems) {
120            this.numItems = numItems;
121        }
122    }
123
124}