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 java.io.Serializable;
24  
25  import org.millscript.commons.alert.alerts.Fault;
26  import org.millscript.commons.util.IList;
27  import org.millscript.commons.util.ListIterator;
28  import org.millscript.commons.util.Maplet;
29  import org.millscript.commons.util.iterator.AbstractListIterator;
30  import org.millscript.commons.util.maplet.IMaplet;
31  
32  /**
33   * This class provides an immutable <code>List</code> implementation which is
34   * backed by a Maplet, i.e. a list of two items, the maplet key and value.
35   */
36  public class IMapletList< V > extends AbstractIList< V > implements Cloneable, Serializable {
37  
38      /**
39       * This is the ID from the release 0.1.0 for future compatibility.
40       */
41      private static final long serialVersionUID = -2742551695906188777L;
42  
43      /**
44       * This class provides a map interator implementation which iterates over
45       * the key and value in a maplet, as a two separate values.
46       */
47      public static class MapletListIterator< V > extends AbstractListIterator< V > {
48  
49          /**
50           * The backing maplet for this iterator.
51           */
52          private final Maplet< V, V > maplet;
53  
54          /**
55           * Constructs a new maplet map iterator to iterate over the key and
56           * value in the specified maplet.
57           *
58           * @param obj   the maplet whose key and value to iterate over
59           */
60          public MapletListIterator( final Maplet< V, V > m ) {
61              this.maplet = m;
62              // If the supplied maplet was null, set the state to pretend we've
63              // reached the end
64              if ( this.maplet == null ) {
65                  super.position = 3;
66              } else {
67                  super.position = 0;
68              }
69          }
70  
71          /**
72           * @see org.millscript.commons.util.iterator.AbstractMapIterator#getValue()
73           */
74          @Override
75          protected V getValue() {
76              if ( super.position == 1 ) {
77                  return this.maplet.getKey();
78              } else {
79                  return this.maplet.getValue();
80              }
81          }
82  
83          /**
84           * @see org.millscript.commons.util.MapIterator#hasNext()
85           */
86          public boolean hasNext() {
87              return super.position == 0 || super.position == 1;
88          }
89  
90          /**
91           * @see org.millscript.commons.util.iterator.AbstractMapIterator#outOfBounds()
92           */
93          @Override
94          protected boolean outOfBounds() {
95              return super.position != 1 && super.position != 2;
96          }
97  
98      }
99  
100     /**
101      * The backing store maplet.
102      */
103     private final Maplet< V, V > store;
104 
105     /**
106      * Constructs a new empty immutable maplet list. 
107      */
108     public IMapletList() {
109         this.store = null;
110     }
111 
112     /**
113      * Constructs a new immutable string list with the specified backing
114      * string.
115      *
116      * @param maplet    the backing maplet
117      */
118     public IMapletList( final Maplet< V, V > maplet ) {
119         this.store = maplet;
120     }
121 
122     /**
123      * @see java.lang.Object#clone()
124      */
125     @Override
126     public Object clone() throws CloneNotSupportedException {
127         // Nothing special required for this clone
128         return super.clone();
129     }
130 
131     /**
132      * @see org.millscript.commons.util.list.AbstractIList#doGet(int)
133      */
134     @Override
135     protected V doGet( final int pos ) {
136         if ( pos == 1 ) {
137             return this.store.getKey();
138         } else if ( pos == 2 ) {
139             return this.store.getValue();
140         }
141         throw new Fault(
142             "Specified position is neither out of bounds or within the list!"
143         ).culprit( "index", pos ).decorate( this ).mishap();
144     }
145 
146     /**
147      * @see org.millscript.commons.util.list.AbstractIList#doSlice(int, int, boolean)
148      */
149     @Override
150     protected IList< V > doSlice( final int first, final int last, boolean share ) {
151         // We know first <= last and first can be either 1 or 2.
152         if ( first == 1 && last == 1 ) {
153             return new ISingletonList< V >( this.store.getKey() );
154         } else if ( first == 2 && last == 2 ) {
155             return new ISingletonList< V >( this.store.getValue() );
156         } else if ( share ) {
157             return this;
158         } else {
159             return new IMapletList< V >(
160                 new IMaplet< V, V >( this.store )
161             );
162         }
163     }
164 
165     /**
166      * @see org.millscript.commons.util.IList#indexOf(java.lang.Object)
167      */
168     public int indexOf( final V value ) {
169         if ( this.store != null ) {
170             if ( value == null ) {
171                 if ( this.store.getKey() == null ) {
172                     return 1;
173                 } else if ( this.store.getValue() == null ) {
174                     return 2;
175                 }
176             } else {
177                 if ( value.equals( this.store.getKey() ) ) {
178                     return 1;
179                 } else if ( value.equals( this.store.getValue() ) ) {
180                     return 2;
181                 }
182             }
183         }
184         return 0;
185     }
186 
187     /**
188      * @see org.millscript.commons.util.IMap#iterator(boolean)
189      */
190     public ListIterator< V > iterator( final boolean share ) {
191         if ( share ) {
192             return new MapletListIterator< V >( this.store );
193         } else {
194             return new MapletListIterator< V >(
195                 new IMaplet< V, V >( this.store.getKey(), this.store.getValue() )
196             );
197         }
198     }
199 
200     /**
201      * @see org.millscript.commons.util.IMap#size()
202      */
203     public int size() {
204         return this.store == null ? 0 : 2;
205     }
206 
207 }