View Javadoc
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 }