1 /*
2 * #%L
3 * Nuiton Utils
4 * %%
5 * Copyright (C) 2004 - 2010 CodeLutin
6 * %%
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU Lesser General Public License as
9 * published by the Free Software Foundation, either version 3 of the
10 * License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Lesser Public License for more details.
16 *
17 * You should have received a copy of the GNU General Lesser Public
18 * License along with this program. If not, see
19 * <http://www.gnu.org/licenses/lgpl-3.0.html>.
20 * #L%
21 */
22
23 package org.nuiton.util;
24
25 import java.util.ArrayList;
26 import java.util.Collection;
27
28 /**
29 * ArrayList with minimum and maximum sizes. For each operation, the size is
30 * checked and the BoundedList to ensure that it is kept in the range.
31 *
32 * Created: 10 juin 2005
33 *
34 * @author Arnaud Thimel - thimel@codelutin.com
35 *
36 */
37 public class BoundedList<E> extends ArrayList<E> {
38 /** */
39 private static final long serialVersionUID = -3211387041114409849L;
40
41 //By defaut, maxSize is set to -1 (infinite)
42 private int minSize = 0;
43
44 private int maxSize = -1;
45
46 /**
47 * Indicates if the list size is at the maximum
48 *
49 * @return true is the maximum size has been reached
50 */
51 public boolean isFull() {
52 return (maxSize == -1 || size() >= maxSize);
53 }
54
55 /**
56 * Indicates if the list size is to the minimum
57 *
58 * @return true is the list size is the minimum size
59 */
60 public boolean isToMinimum() {
61 return (size() <= minSize);
62 }
63
64 /**
65 * Creates a new BoundedList with the specified initialCapacity. The min size is set to 0 and the max size to the infinite.
66 *
67 * @param initialCapacity FIXME
68 */
69 public BoundedList(int initialCapacity) {
70 super(initialCapacity);
71 }
72
73 /** Creates a new BoundedList with the default capacity. The min size is set to 0 and the max size to the infinite. */
74 public BoundedList() {
75 super();
76 }
77
78 /**
79 * Creates a new BoundedList with the specified collection of elements. The min size is set to 0 and the max size to the infinite.
80 *
81 * @param arg0 FIXME
82 */
83 public BoundedList(Collection<E> arg0) {
84 super(arg0);
85 }
86
87 /**
88 * Creates a new empty BoundedList with the specified min and max sizes. Please be informed that -1 represents the infinite.
89 *
90 * @param minSize FIXME
91 * @param maxSize FIXME
92 */
93 public BoundedList(int minSize, int maxSize) {
94 super();
95 if (minSize > 0)
96 this.minSize = minSize;
97 if (minSize > -1)
98 this.maxSize = maxSize;
99 }
100
101 /**
102 * Appends the specified element to the end of this list.
103 *
104 * @param o the Object to be added
105 */
106 @Override
107 public boolean add(E o) {
108 if (checkNewSize(1))
109 return super.add(o);
110 else
111 throw getException("Cannot add element. Use set to replace element or remove to free space or addAll");
112 }
113
114 /**
115 * Inserts the specified element at the specified position in this list.
116 *
117 * @param index the position where to add the Object
118 * @param o the Object to be added
119 */
120 @Override
121 public void add(int index, E o) {
122 if (checkNewSize(1))
123 super.add(index, o);
124 else
125 throw getException("Cannot add element. Use set to replace element or remove to free space or addAll");
126 }
127
128 /**
129 * Appends all of the elements in the specified Collection to the end of this list, in the order that they are returned by the specified Collection's Iterator.
130 *
131 * @param c the collection of Objects to be added
132 */
133 @Override
134 public boolean addAll(Collection<? extends E> c) {
135 if (checkNewSize(c.size()))
136 return super.addAll(c);
137 else
138 throw getException("Cannot add element. Use set to replace element or remove to free space or addAll");
139 }
140
141 /**
142 * Inserts all of the elements in the specified Collection into this list, starting at the specified position.
143 *
144 * @param index the index where to start adding the collection of objects
145 * @param c the collection of Objects to be added
146 */
147 @Override
148 public boolean addAll(int index, Collection<? extends E> c) {
149 if (checkNewSize(c.size()))
150 return super.addAll(index, c);
151 else
152 throw getException("Cannot add element. Use set to replace element or remove to free space or addAll");
153 }
154
155 /** Returns a shallow copy of this BoundedList instance */
156 @SuppressWarnings("unchecked")
157 @Override
158 public Object clone() {
159 BoundedList<E> bL = (BoundedList<E>) super.clone();
160 bL.minSize = minSize;
161 bL.maxSize = maxSize;
162 return bL;
163 }
164
165 /*
166 public Object set(int index, Object o) {
167 //Pas d'action particulière à priori
168 return super.set(index, o);
169 }
170 */
171
172 /**
173 * Removes the element at the specified position in this list.
174 *
175 * @param index the position of the element to be removed
176 */
177 @Override
178 public E remove(int index) {
179 if (checkNewSize(-1))
180 return super.remove(index);
181 else
182 throw getException("Cannot remove element, minSize is " + minSize);
183 }
184
185 /**
186 * Removes from this List all of the elements whose index is between fromIndex, inclusive and toIndex, exclusive.
187 *
188 * @param fromIndex index of first element to be removed
189 * @param toIndex index after last element to be removed
190 */
191 @Override
192 protected void removeRange(int fromIndex, int toIndex) {
193 if (checkNewSize(-(toIndex - fromIndex)))
194 super.removeRange(fromIndex, toIndex);
195 else
196 throw getException("Cannot remove element, minSize is " + minSize);
197 }
198
199 /** Removes a single instance of the specified element from this list, if it is present (optional operation). */
200 @Override
201 public boolean remove(Object o) {
202 if (checkNewSize(-1) || !contains(o))
203 return super.remove(o);
204 else
205 throw getException("Cannot remove element, minSize is " + minSize);
206 }
207
208 /** Removes from this collection all of its elements that are contained in the specified collection (optional operation). */
209 @Override
210 public boolean removeAll(Collection<?> c) {
211 //On ne sait pas si les éléments de la Collection sont contenus dans la liste.
212 //De plus, on ne sait pas si les instances sont présentes un ou plusieurs fois (Si elles y sont +sieurs fois elles sont supprimées +sieurs fois)
213 if (checkNewSize(-c.size()))
214 return super.removeAll(c);
215 else
216 throw getException("Cannot remove element, minSize is " + minSize);
217 }
218
219 private boolean checkNewSize(int size) {
220 if (size == 0) //Pas de changement de taille !
221 return (((size()) >= minSize) && ((maxSize == -1) || (size() <= maxSize)));
222 else if (size > 0) //Ajout d'un elem - vérification qu'on ne dépasse pas la borne max
223 return ((maxSize == -1) || ((size() + size) <= maxSize));
224 return ((size() + size) >= minSize); //Suppression d'un élem - on vérifie qu'on ne descend pas en dessous de la borne min
225 }
226
227 private RuntimeException getException(String msg) {
228 return new BoundedListOutOfBoundsException(msg);
229 }
230
231 @Override
232 public String toString() {
233 return /*"(" + minSize + ", " + maxSize + ") " +*/ super.toString();
234 }
235 }