View Javadoc

1   ////////////////////////////////////////////////////////////////////////////////
2   // MillScript-Util: an Open Spice interpreter and batch website creation tool
3   // Copyright (C) 2005 Kevin Rogers
4   //
5   // This file is part of MillScript-Util.
6   //
7   // MillScript-Util is free software; you can redistribute it and/or modify it under
8   // the terms of the GNU General Public License as published by the Free
9   // Software Foundation; either version 2 of the License, or (at your option)
10  // any later version.
11  //
12  // MillScript-Util is distributed in the hope that it will be useful, but WITHOUT
13  // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14  // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
15  // more details.
16  //
17  // You should have received a copy of the GNU General Public License along with
18  // MillScript-Util; if not, write to the Free Software Foundation, Inc., 59 Temple
19  // Place, Suite 330, Boston, MA  02111-1307  USA
20  ////////////////////////////////////////////////////////////////////////////////
21  package org.millscript.commons.util.list;
22  
23  import org.millscript.commons.util.EList;
24  import org.millscript.commons.util.IList;
25  import org.millscript.commons.util.ListIterator;
26  import org.millscript.commons.util.Maplet;
27  import org.millscript.commons.util.alerts.InvalidIndexForListsAlert;
28  import org.millscript.commons.util.alerts.ListIndexOutOfBoundsAlert;
29  
30  /**
31   * 
32   */
33  public abstract class AbstractEList< V > extends AbstractUList< V > implements EList< V > {
34  
35      /**
36       * @see org.millscript.commons.util.EList#append(org.millscript.commons.util.IList)
37       */
38      public void append( final IList< ? extends V > list ) {
39          // Iterate over all the values in the supplied list, appending them to
40          // this one. NOTE - we want the iterator to share backing store here
41          for ( ListIterator< ? extends V > it = list.iterator( true ); it.hasNext(); ) {
42              // We append the values, as the keys are the indices
43              this.addLast( it.nextValue() );
44          }
45      }
46  
47      /**
48       * @see org.millscript.commons.util.EList#delete(int, V)
49       */
50      public void delete( final int pos, final V value ) {
51          // pos from 1 to length
52          if ( pos < 1 || pos > this.size() ) {
53              throw new ListIndexOutOfBoundsAlert().culprit(
54                  "index",
55                  pos
56              ).decorate( this ).mishap();
57          }
58          this.doDelete( pos, value );
59      }
60  
61      /**
62       * @see org.millscript.commons.util.EList#delete(java.lang.Integer, java.lang.Object)
63       */
64      public void delete( final Integer pos, final V value ) {
65          if ( pos == null ) {
66              throw new InvalidIndexForListsAlert().culprit(
67                  "key",
68                  pos
69              ).decorate( this ).mishap();
70          }
71          this.delete( pos.intValue(), value );
72      }
73  
74      /**
75       * @see org.millscript.commons.util.EList#delete(org.millscript.commons.util.Maplet)
76       */
77      public void delete( final Maplet< ? extends Integer, ? extends V > entry ) {
78          this.delete( entry.getKey(), entry.getValue() );
79      }
80  
81      /**
82       * @see org.millscript.commons.util.EList#delete0(int, java.lang.Object)
83       */
84      public void delete0( final int pos, final V value ) {
85          this.delete( pos + 1, value );
86      }
87  
88      /**
89       * @see org.millscript.commons.util.EList#delete0(java.lang.Integer, java.lang.Object)
90       */
91      public void delete0( final Integer pos, final V value ) {
92          if ( pos == null ) {
93              throw new InvalidIndexForListsAlert().culprit(
94                  "key",
95                  pos
96              ).decorate( this ).mishap();
97          }
98          this.delete0( pos.intValue(), value );
99      }
100 
101     /**
102      * @see org.millscript.commons.util.EList#delete0(org.millscript.commons.util.Maplet)
103      */
104     public void delete0( final Maplet< ? extends Integer, ? extends V > entry ) {
105         this.delete0( entry.getKey(), entry.getValue() );
106     }
107 
108     /**
109      * @see org.millscript.commons.util.EList#deleteAll(org.millscript.commons.util.IList)
110      */
111     public void deleteAll( final IList< ? extends V > list ) {
112         final ListIterator< ? extends V > it = list.iterator( true );
113         while ( it.hasNext() ) {
114             this.deleteValue( it.nextValue() );
115         }
116     }
117 
118 //    /**
119 //     * @see org.millscript.commons.util.EList#deleteAll(org.millscript.commons.util.Map)
120 //     */
121 //    public void deleteAll( final Map map ) {
122 //        // We can't do any shortcuts as we need to compare the positions of the
123 //        // values within a list, so we will always need to do this long hand.
124 //        // NOTE - we want the iterator to share backing store here
125 //        final MapIterator it = map.iterator( true );
126 //        int removedValues = 0;
127 //        while ( it.hasNext() ) {
128 //            try {
129 //                final int key = ((Integer) it.nextKey()).intValue();
130 //                // We have to subtract the number of removed values from the
131 //                // maps key, as each time we remove a entry from this list its
132 //                // subsequent entries shift left one position.
133 //                this.delete( key - removedValues++, it.currentValue() );
134 //            } catch ( ClassCastException ex ) {
135 //                throw new InvalidIndexForListsAlert().culprit(
136 //                    "key",
137 //                    it.currentKey()
138 //                ).decorate( this ).mishap();
139 //            } catch ( NullPointerException ex ) {
140 //                throw new InvalidIndexForListsAlert().culprit(
141 //                    "key",
142 //                    it.currentKey()
143 //                ).decorate( this ).mishap();
144 //            }
145 //        }
146 //    }
147 //
148 //    /**
149 //     * @see org.millscript.commons.util.EList#deleteAll0(org.millscript.commons.util.Map)
150 //     */
151 //    public void deleteAll0( final Map map ) {
152 //        // We can't do any shortcuts as we need to compare the positions of the
153 //        // values within a list, so we will always need to do this long hand.
154 //        // NOTE - we want the iterator to share backing store here
155 //        final MapIterator it = map.iterator( true );
156 //        int removedValues = 0;
157 //        while ( it.hasNext() ) {
158 //            try {
159 //                final int key = ((Integer) it.nextKey()).intValue();
160 //                // We have to subtract the number of removed values from the
161 //                // maps key, as each time we remove a entry from this list its
162 //                // subsequent entries shift left one position.
163 //                this.delete0( key - removedValues++, it.currentValue() );
164 //            } catch ( ClassCastException ex ) {
165 //                throw new InvalidIndexForListsAlert().culprit(
166 //                    "key",
167 //                    it.currentKey()
168 //                ).decorate( this ).mishap();
169 //            } catch ( NullPointerException ex ) {
170 //                throw new InvalidIndexForListsAlert().culprit(
171 //                    "key",
172 //                    it.currentKey()
173 //                ).decorate( this ).mishap();
174 //            }
175 //        }
176 //    }
177 
178     /**
179      * @see org.millscript.commons.util.EList#deleteKey(int)
180      */
181     public void deleteKey( final int key ) {
182         // pos from 1 to length
183         if ( key < 1 || key > this.size() ) {
184             throw new ListIndexOutOfBoundsAlert().culprit(
185                 "index",
186                 key
187             ).decorate( this ).mishap();
188         }
189         this.doDeleteKey( key );
190     }
191 
192     /**
193      * @see org.millscript.commons.util.EList#deleteKey(java.lang.Integer)
194      */
195     public void deleteKey( final Integer key ) {
196         if ( key == null ) {
197             throw new InvalidIndexForListsAlert().culprit(
198                 "key",
199                 key
200             ).decorate( this ).mishap();
201         }
202         this.deleteKey( key.intValue() );
203     }
204 
205     /**
206      * @see org.millscript.commons.util.EList#deleteKey0(int)
207      */
208     public void deleteKey0( final int key ) {
209         this.deleteKey( key + 1 );
210     }
211 
212     /**
213      * @see org.millscript.commons.util.EList#deleteKey0(java.lang.Integer)
214      */
215     public void deleteKey0( final Integer key ) {
216         if ( key == null ) {
217             throw new InvalidIndexForListsAlert().culprit(
218                 "key",
219                 key
220             ).decorate( this ).mishap();
221         }
222         this.deleteKey0( key.intValue() );
223     }
224 
225     /**
226      * @see org.millscript.commons.util.EList#deleteSlice(int, int)
227      */
228     public void deleteSlice( final int first, final int last ) {
229         if ( first > last ) {
230             // Do nothing
231         } else if ( first < 1 || first > this.size() ) {
232             throw new ListIndexOutOfBoundsAlert(
233                 "First index in slice must be between 1 and the length of the list"
234             ).culprit(
235                 "index",
236                 first
237             ).decorate( this ).mishap();
238         } else if ( last > this.size() ) {
239             throw new ListIndexOutOfBoundsAlert(
240                 "Last index in slice must not be greater than the length of the list"
241             ).culprit(
242                 "index",
243                 first
244             ).decorate( this ).mishap();
245         } else {
246             this.doRemoveSlice( first, last );
247         }
248     }
249 
250     /**
251      * @see org.millscript.commons.util.EList#deleteSlice0(int, int)
252      */
253     public void deleteSlice0( final int first, final int last ) {
254         this.deleteSlice( first + 1, last + 1 );
255     }
256 
257     /**
258      * Removes the value at the specified position(one based) in the list, but
259      * only if it matches the specified one. If the element is sucessfully
260      * deleted, any subsequent elements are shifted to an index one lower than
261      * before. This method is called by the generic
262      * {@link #doDelete(int, Object)} method after the index has been
263      * validated. Hence this method should generally not need to perform any
264      * further validation.
265      *
266      * @param pos   the index(one based) of the object to remove 
267      * @param value the value which must match that stored at the specified
268      * position(one based) in the list
269      */
270     protected abstract void doDelete( final int key, final V value );
271 
272     /**
273      * Removes the value at the specified index(one based), shifting any
274      * subsequent elements to an index one lower than before. This method is
275      * called by the generic {@link #doDeleteKey(int)} method after the index
276      * has been validated. Hence this method should generally not need to
277      * perform any further validation.
278      *
279      * @param key   the index(one based) of the value to remove
280      */
281     protected abstract void doDeleteKey( final int key );
282 
283     /**
284      * Removes the specified slice of elements in this list, starting
285      * at <code>first</code>(one based, inclusive) and continuing
286      * <code>last</code>(one based, inclusive). This method is called by the
287      * generic {@link #deleteSlice(int, int)} method after the index has been
288      * validated. Hence this method should generally not need to perform any
289      * further validation.
290      *
291      * @param first the index(one based) of the first element in the slice
292      * @param last  the index(one based) of the last element in the slice
293      */
294     protected abstract void doRemoveSlice( int first, int last );
295 
296     /**
297      * @see org.millscript.commons.util.EList#insert(org.millscript.commons.util.Maplet)
298      */
299     public void insert( final Maplet< ? extends Integer, ? extends V > entry ) {
300         this.insert( entry.getKey(), entry.getValue() );
301     }
302 
303     /**
304      * @see org.millscript.commons.util.EList#insert(java.lang.Integer, java.lang.Object)
305      */
306     public void insert( final Integer pos, final V value ) {
307         if ( pos == null ) {
308             throw new InvalidIndexForListsAlert().culprit(
309                 "key",
310                 pos
311             ).decorate( this ).mishap();
312         }
313         this.insert( pos.intValue(), value );
314     }
315 
316     /**
317      * @see org.millscript.commons.util.EList#insert0(int, java.lang.Object)
318      */
319     public void insert0( final int pos, final V value ) {
320         this.insert( pos + 1, value );
321     }
322 
323     /**
324      * @see org.millscript.commons.util.EList#insert0(java.lang.Integer, java.lang.Object)
325      */
326     public void insert0( final Integer pos, final V value ) {
327         if ( pos == null ) {
328             throw new InvalidIndexForListsAlert().culprit(
329                 "key",
330                 pos
331             ).decorate( this ).mishap();
332         }
333         this.insert0( pos.intValue(), value );
334     }
335 
336     /**
337      * @see org.millscript.commons.util.EList#insert0(org.millscript.commons.util.Maplet)
338      */
339     public void insert0( final Maplet< ? extends Integer, ? extends V > entry ) {
340         this.insert0( entry.getKey(), entry.getValue() );
341     }
342 
343 //    /**
344 //     * @see org.millscript.commons.util.EList#insertAll(org.millscript.commons.util.Map)
345 //     */
346 //    public void insertAll( final Map map ) {
347 //        // Iterate over all the mappings in the supplied map, inserting them
348 //        // into this one.
349 //        final MapIterator it = map.iterator( true );
350 //        for ( int i = 0; it.hasNext(); i++ ) {
351 //            try {
352 //                final int key = ((Integer) it.nextKey()).intValue();
353 //                // For each maplet value we insert we add one to the maplet
354 //                // key. This accounts for the fact that we've inserted an item
355 //                // into the list and all its subsequent indices
356 //                this.insert( key + i, it.currentValue() );
357 //            } catch ( ClassCastException ex ) {
358 //                throw new InvalidIndexForListsAlert().culprit(
359 //                    "key",
360 //                    it.currentKey()
361 //                ).decorate( this ).mishap();
362 //            } catch ( NullPointerException ex ) {
363 //                throw new InvalidIndexForListsAlert().culprit(
364 //                    "key",
365 //                    it.currentKey()
366 //                ).decorate( this ).mishap();
367 //            }
368 //        }
369 //    }
370 //
371 //    /**
372 //     * @see org.millscript.commons.util.EList#insertAll0(org.millscript.commons.util.Map)
373 //     */
374 //    public void insertAll0( final Map map ) {
375 //        // Iterate over all the mappings in the supplied map, inserting them
376 //        // into this one.
377 //        final MapIterator it = map.iterator( true );
378 //        for ( int i = 0; it.hasNext(); i++ ) {
379 //            try {
380 //                final int key = ((Integer) it.nextKey()).intValue();
381 //                // For each maplet value we insert we add one to the maplet
382 //                // key. This accounts for the fact that we've inserted an item
383 //                // into the list and all its subsequent indices
384 //                this.insert( key + i, it.currentValue() );
385 //            } catch ( ClassCastException ex ) {
386 //                throw new InvalidIndexForListsAlert().culprit(
387 //                    "key",
388 //                    it.currentKey()
389 //                ).decorate( this ).mishap();
390 //            } catch ( NullPointerException ex ) {
391 //                throw new InvalidIndexForListsAlert().culprit(
392 //                    "key",
393 //                    it.currentKey()
394 //                ).decorate( this ).mishap();
395 //            }
396 //        }
397 //    }
398 
399     /**
400      * @see org.millscript.commons.util.EList#prefix(org.millscript.commons.util.IList)
401      */
402     public void prefix( final IList< ? extends V > list ) {
403         // Iterate over all the values in the supplied list, prefixing them to
404         // this one. NOTE - we want the iterator to share backing store here
405         final ListIterator< ? extends V > it = list.iterator( true );
406         for ( int i = 1; it.hasNext(); i++ ) {
407             this.insert( i, it.nextValue() );
408         }
409     }
410 
411 }