1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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
63
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
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
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 }