/* * Copyright (C) 2012 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.motorolamobility.preflighting.core.utils; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.List; import com.motorolamobility.preflighting.core.exception.ValidationLimitException; /** * An implementation of ArrayList that will throw an {@link ValidationLimitException} if its size is bigger than maxSize after an item addition. * If UNLIMITED is passed as maxSize during list construction {@link LimitedList} will behave exactly like {@link ArrayList}. * For more information regarding the behavior of the list @see ArrayList. */ public class LimitedList<T> extends ArrayList<T> { private static final long serialVersionUID = 7066195136542105428L; /** * Constant that determines if this List is unlimited, when used as MaxSize. */ public static final int UNLIMITED = -1; /** * Flag indicating that this is an unlimited list. */ private boolean unlimited = false; /** * The max size of this list. */ private int maxSize = 0; /** * Constructs an empty list with an initial capacity of ten elements. * In order to construct an unlimited list use UNLIMITED as maxSize. * @param maxSize this list maxSize, must be greater than zero or UNLIMITED. * @exception IllegalArgumentException if the specified maxSize * is not greater than zero. */ public LimitedList(int maxSize) { this(10, maxSize); } /** * Constructs an empty list with the specified initial capacity. * In order to construct an unlimited list use UNLIMITED as maxSize. * @param initialCapacity the initial capacity of the list. * @param maxSize this list maxSize, must be greater than zero or UNLIMITED. * @exception IllegalArgumentException if the specified maxSize or initialCapacity * is not greater than zero. */ public LimitedList(int initialCapacity, int maxSize) { super(initialCapacity); if ((maxSize < 0) && (maxSize != UNLIMITED)) { throw new IllegalArgumentException( "Max size must be a positive integer or LimitedList.UNLIMITED"); } this.maxSize = maxSize; unlimited = maxSize == UNLIMITED; } /* * (non-Javadoc) * @see java.util.ArrayList#add(java.lang.Object) */ @Override public boolean add(T element) { if (!exceedsMaxSize(1)) { return super.add(element); } else { throw new ValidationLimitException(); } } /* * (non-Javadoc) * @see java.util.ArrayList#add(int, java.lang.Object) */ @Override public void add(int index, T element) { if (!exceedsMaxSize(1)) { super.add(index, element); } else { throw new ValidationLimitException(); } } /* * (non-Javadoc) * @see java.util.ArrayList#addAll(java.util.Collection) */ @Override public boolean addAll(Collection<? extends T> c) { if (!exceedsMaxSize(c.size())) { return super.addAll(c); } else { List<T> allowedSubList = getAllowedList(c); super.addAll(allowedSubList); throw new ValidationLimitException(); } } /* * (non-Javadoc) * @see java.util.ArrayList#addAll(int, java.util.Collection) */ @Override public boolean addAll(int index, Collection<? extends T> c) { if (!exceedsMaxSize(c.size())) { return super.addAll(index, c); } else { List<T> allowedSubList = getAllowedList(c); super.addAll(index, allowedSubList); throw new ValidationLimitException(); } } /** * Retrieves a subset of c containing all elements that can still be added into this list. */ private List<T> getAllowedList(Collection<? extends T> c) { int allowed = maxSize - size(); @SuppressWarnings("unchecked") T[] toBeAdded = (T[]) new Object[maxSize]; System.arraycopy(c.toArray(), 0, toBeAdded, 0, allowed); List<T> allowedSubList = Arrays.asList(toBeAdded); return allowedSubList; } /** * Verifies if it's possible to add a given number of elements into * the list, without exceeding its maxSize. * @param newElementsCount number of elements to be added * @return true if newElementsCount would exceed maxSize if added */ private boolean exceedsMaxSize(int newElementsCount) { boolean exceedsMaxSize = false; if (!unlimited) { if ((size() + newElementsCount) > maxSize) { exceedsMaxSize = true; } } return exceedsMaxSize; } /** * @return the maxSize */ public int getMaxSize() { return maxSize; } /** * @param maxSize the maxSize to set */ public void setMaxSize(int maxSize) { this.maxSize = maxSize; } /** * @return the unlimited */ public boolean isUnlimited() { return unlimited; } }