001/* 
002 * Copyright (c) 2006-2011 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the Eclipse Public License v1.0
006 * which accompanies this distribution, and is available at
007 * http://www.eclipse.org/legal/epl-v10.html
008 *
009 * Contributors:
010 *     Florent Guillaume
011 */
012package org.nuxeo.ecm.core.opencmis.impl.util;
013
014import java.math.BigInteger;
015import java.util.Collections;
016import java.util.List;
017
018/**
019 * Utilities around lists.
020 */
021public class ListUtils {
022
023    private ListUtils() {
024        // utility class
025    }
026
027    /**
028     * Returns a batched version of the list, according to the passed parameters.
029     *
030     * @param list the list
031     * @param maxItems the maximum number of items, or {@code null} for the default
032     * @param skipCount the skip count
033     * @param defaultMax the default maximum number of items if {@code maxItems} is {@code null}
034     * @return the batched list, which may be a sublist per {@link List#subList}
035     */
036    public static <T> List<T> batchList(List<T> list, BigInteger maxItems, BigInteger skipCount, int defaultMax) {
037        return getBatchedList(list, maxItems, skipCount, defaultMax).getList();
038    }
039
040    /**
041     * Returns a batched version of the list, according to the passed parameters.
042     *
043     * @param list the list
044     * @param maxItems the maximum number of items, or {@code null} for the default
045     * @param skipCount the skip count
046     * @param defaultMax the default maximum number of items if {@code maxItems} is {@code null}
047     * @return the batched list, which may be a sublist per {@link List#subList}
048     */
049    public static <T> BatchedList<T> getBatchedList(List<T> list, BigInteger maxItems, BigInteger skipCount,
050            int defaultMax) {
051        int skip = skipCount == null ? 0 : skipCount.intValue();
052        if (skip < 0) {
053            skip = 0;
054        }
055        int max = maxItems == null ? -1 : maxItems.intValue();
056        if (max < 0) {
057            max = defaultMax;
058        }
059        BatchedList<T> res = new BatchedList<T>();
060        res.setNumItems(list.size());
061        if (skip >= list.size()) {
062            res.setHasMoreItems(false);
063            res.setList(Collections.<T> emptyList());
064            return res;
065        }
066        if (max > list.size() - skip) {
067            max = list.size() - skip;
068        }
069        boolean hasMoreItems = max < list.size() - skip;
070        if (skip > 0 || hasMoreItems) {
071            list = list.subList(skip, skip + max);
072        }
073        res.setHasMoreItems(hasMoreItems);
074        res.setList(list);
075        return res;
076    }
077
078    /**
079     * A holder for a sublist of a list, a flag indicating if there were more elements after the included sublist, and
080     * the total number of items if there had been no batching.
081     *
082     * @param <T> the type of the list elements
083     */
084    public static class BatchedList<T> {
085
086        public List<T> list;
087
088        public boolean hasMoreItems = false;
089
090        public int numItems;
091
092        public List<T> getList() {
093            return list;
094        }
095
096        public void setList(List<T> list) {
097            this.list = list;
098        }
099
100        public Boolean getHasMoreItems() {
101            return Boolean.valueOf(hasMoreItems);
102        }
103
104        public void setHasMoreItems(boolean hasMoreItems) {
105            this.hasMoreItems = hasMoreItems;
106        }
107
108        public BigInteger getNumItems() {
109            return BigInteger.valueOf(numItems);
110        }
111
112        public void setNumItems(int numItems) {
113            this.numItems = numItems;
114        }
115    }
116
117}