1
2
3
4 package org.sourceforge.jemm.collections;
5
6 import java.util.ArrayList;
7 import java.util.Arrays;
8 import java.util.Collection;
9 import java.util.Collections;
10 import java.util.Iterator;
11 import java.util.List;
12 import java.util.ListIterator;
13
14 import org.sourceforge.jemm.collections.internal.ClearRequest;
15 import org.sourceforge.jemm.collections.internal.ContainsRequest;
16 import org.sourceforge.jemm.collections.internal.ContainsResponse;
17 import org.sourceforge.jemm.collections.internal.RemoveRequest;
18 import org.sourceforge.jemm.collections.internal.RemoveResponse;
19 import org.sourceforge.jemm.collections.internal.SizeRequest;
20 import org.sourceforge.jemm.collections.internal.SizeResponse;
21 import org.sourceforge.jemm.collections.internal.StoredValue;
22 import org.sourceforge.jemm.collections.internal.ToArrayRequest;
23 import org.sourceforge.jemm.collections.internal.ToArrayResponse;
24 import org.sourceforge.jemm.collections.internal.list.ListAddAllRequest;
25 import org.sourceforge.jemm.collections.internal.list.ListAddAllResponse;
26 import org.sourceforge.jemm.collections.internal.list.ListAddRequest;
27 import org.sourceforge.jemm.collections.internal.list.ListAddResponse;
28 import org.sourceforge.jemm.collections.internal.list.ListGetRequest;
29 import org.sourceforge.jemm.collections.internal.list.ListGetResponse;
30 import org.sourceforge.jemm.collections.internal.list.ListIndexOfRequest;
31 import org.sourceforge.jemm.collections.internal.list.ListIndexOfResponse;
32 import org.sourceforge.jemm.collections.internal.list.ListRemoveIndexRequest;
33 import org.sourceforge.jemm.collections.internal.list.ListRemoveIndexResponse;
34 import org.sourceforge.jemm.collections.internal.list.ListSetRequest;
35 import org.sourceforge.jemm.collections.internal.list.ListSetResponse;
36 import org.sourceforge.jemm.collections.internal.list.SubListRequest;
37 import org.sourceforge.jemm.collections.internal.list.SubListResponse;
38 import org.sourceforge.jemm.lifecycle.ShadowTypeObject;
39 import org.sourceforge.jemm.util.JEMMType;
40
41
42
43
44
45
46
47
48 public final class JemmList<K> extends JEMMType implements List<K> {
49
50
51 public JemmList() {
52 super();
53 }
54
55
56
57
58 protected JemmList(ShadowTypeObject jemmOIF) {
59 super(jemmOIF);
60 }
61
62 public boolean add(K uValue) {
63 return ((ListAddResponse) jemmOIF.processRequest(new ListAddRequest(new StoredValue(uValue)))).isModified();
64 }
65
66 public void add(int index, K uValue) {
67 jemmOIF.processRequest(new ListAddRequest(index,new StoredValue(uValue)));
68 }
69
70 public boolean addAll(Collection<? extends K> c) {
71 List<StoredValue> list = new ArrayList<StoredValue>(c.size());
72 for (Object uValue : c)
73 list.add(new StoredValue(uValue));
74
75 StoredValue[] values = list.toArray(new StoredValue[0]);
76
77 return ((ListAddAllResponse) jemmOIF.processRequest(new ListAddAllRequest(values))).isModified();
78 }
79
80 public boolean addAll(int index, Collection<? extends K> c) {
81 List<StoredValue> list = new ArrayList<StoredValue>(c.size());
82 for (Object uValue : c)
83 list.add(new StoredValue(uValue));
84
85 StoredValue[] values = list.toArray(new StoredValue[0]);
86
87 return ((ListAddAllResponse) jemmOIF.processRequest(new ListAddAllRequest(index,values))).isModified();
88 }
89
90 public void clear() {
91 jemmOIF.processRequest(new ClearRequest());
92 }
93
94 public boolean contains(Object value) {
95 ContainsResponse result = (ContainsResponse) jemmOIF.processRequest(new ContainsRequest(value));
96 if(result.isFound())
97 return true;
98 else
99 if(result.getPossibles() != null)
100 for (Object possible : result.getPossibles())
101 if(value != null && value.equals(possible))
102 return true;
103 return false;
104 }
105
106 public boolean containsAll(Collection<?> c) {
107 throw new UnsupportedOperationException("JemmList does not currently support removeAll()");
108 }
109
110 @SuppressWarnings("unchecked")
111 public K get(int index) {
112 return (K) ((ListGetResponse) jemmOIF.processRequest(new ListGetRequest(index))).getValue();
113 }
114
115 public int indexOf(Object value) {
116 return listIndexInternal(value,false);
117 }
118
119 private int listIndexInternal(Object value, boolean reverse) {
120 ListIndexOfResponse resp = (ListIndexOfResponse) jemmOIF.processRequest(
121 new ListIndexOfRequest(new StoredValue(value),reverse));
122
123 if(resp.getIndex() != -1)
124 return resp.getIndex();
125
126 if(resp.hasPossibles()) {
127 Object[] possibleValues = resp.getPossibleMatches();
128 int[] possibleIndexes = resp.getPossibleIndexes();
129 for(int i=0; i<possibleValues.length; i++)
130 if(value == possibleValues || value.equals(possibleValues[i]))
131 return possibleIndexes[i];
132 }
133
134 return -1;
135 }
136
137 public boolean isEmpty() {
138 return size() == 0;
139 }
140
141 public Iterator<K> iterator() {
142 return listIterator();
143 }
144
145 public int lastIndexOf(Object uValue) {
146 return listIndexInternal(uValue, true);
147 }
148
149 public ListIterator<K> listIterator() {
150 return listIterator(0);
151 }
152
153 @SuppressWarnings("unchecked")
154 public ListIterator<K> listIterator(int index) {
155 Object[] data = toArray();
156 List<Object> list = new ArrayList<Object>(data.length);
157 for(Object obj : data)
158 list.add(obj);
159
160 list = Collections.unmodifiableList(list);
161 return (ListIterator<K>) list.listIterator(index);
162 }
163
164 public boolean remove(Object uValue) {
165
166
167 RemoveRequest req = new RemoveRequest(new StoredValue(uValue));
168 while(true) {
169 RemoveResponse resp = (RemoveResponse) jemmOIF.processRequest(req);
170 if(resp.wasRemoved())
171 return true;
172
173 if(resp.getPotentialMatches() == null)
174 return false;
175
176 Object target = null;
177 for(int i=0; i<resp.getPotentialMatches().length && target == null; i++)
178 for (Object possible : resp.getPotentialMatches())
179 if(uValue == possible || (uValue != null && uValue.equals(possible)))
180 target = possible;
181
182 req = new RemoveRequest(new StoredValue(target));
183 }
184 }
185
186 @SuppressWarnings("unchecked")
187 public K remove(int index) {
188 return (K) ((ListRemoveIndexResponse) jemmOIF.processRequest(new ListRemoveIndexRequest(index))).getValue();
189 }
190
191 public boolean removeAll(Collection<?> uCollection) {
192 throw new UnsupportedOperationException("JemmList does not currently support removeAll()");
193 }
194
195 public boolean retainAll(Collection<?> uCollection) {
196 throw new UnsupportedOperationException("JemmList does not currently support retainAll()");
197 }
198
199 @SuppressWarnings("unchecked")
200 public K set(int index, K uValue) {
201 return (K) ((ListSetResponse) jemmOIF.processRequest(
202 new ListSetRequest(index,new StoredValue(uValue)))).getOldValue();
203 }
204
205 public int size() {
206 return ((SizeResponse) jemmOIF.processRequest(new SizeRequest())).getSize();
207 }
208
209 @SuppressWarnings("unchecked")
210 public List<K> subList(int fromIndex, int toIndex) {
211 SubListResponse resp = (SubListResponse) jemmOIF.processRequest(new SubListRequest(fromIndex,toIndex));
212 return (JemmList<K>) resp.getList();
213 }
214
215 public Object[] toArray() {
216 return ((ToArrayResponse) jemmOIF.processRequest(new ToArrayRequest())).getArray();
217 }
218
219 @SuppressWarnings("unchecked")
220 public <T> T[] toArray(T[] a) {
221 Object[] curValues = toArray();
222 int size = curValues.length;
223 if (a.length < size) {
224
225
226 return (T[]) Arrays.copyOf(curValues, size, a.getClass());
227 }
228
229 System.arraycopy(curValues, 0, a, 0, size);
230 if (a.length > size)
231 a[size] = null;
232 return a;
233 }
234 }