source:
java/main/src/main/java/com/framsticks/params/UniqueListAccess.java
@
98
Last change on this file since 98 was 98, checked in by , 11 years ago | |
---|---|
File size: 5.9 KB |
Line | |
---|---|
1 | package com.framsticks.params; |
2 | |
3 | import com.framsticks.util.FramsticksException; |
4 | import com.framsticks.util.UnimplementedException; |
5 | import com.framsticks.util.UnsupportedOperationException; |
6 | import com.framsticks.util.lang.Casting; |
7 | import com.framsticks.util.lang.Numbers; |
8 | import org.apache.log4j.Logger; |
9 | |
10 | import java.util.*; |
11 | |
12 | /** |
13 | * @author Piotr Sniegowski |
14 | */ |
15 | public class UniqueListAccess extends ListAccess { |
16 | |
17 | private static final Logger log = Logger.getLogger(UniqueListAccess.class); |
18 | |
19 | Map<String, Object> map; |
20 | |
21 | final String uidName; |
22 | |
23 | public UniqueListAccess(AccessInterface elementAccess, String uidName) { |
24 | super(elementAccess); |
25 | this.uidName = uidName; |
26 | } |
27 | |
28 | public static Integer getUidNumber(String uid) { |
29 | try { |
30 | return Integer.valueOf(uid.substring(1)); |
31 | } catch (NumberFormatException e) { |
32 | return null; |
33 | } |
34 | } |
35 | |
36 | public static class UidComparator implements Comparator<String> { |
37 | |
38 | protected String name; |
39 | |
40 | /** |
41 | * @param name |
42 | */ |
43 | public UidComparator(String name) { |
44 | this.name = name; |
45 | } |
46 | |
47 | @Override |
48 | public int compare(String a, String b) { |
49 | if (a.equals(b)) { |
50 | return 0; |
51 | } |
52 | int diff = a.length() - b.length(); |
53 | if (diff != 0) { |
54 | return diff; |
55 | } |
56 | Integer au = getUidNumber(a); |
57 | Integer bu = getUidNumber(b); |
58 | if (au == null || bu == null) { |
59 | throw new FramsticksException().msg("comparator failure").arg("left", a).arg("right", b).arg("in", this); |
60 | } |
61 | return au - bu; |
62 | } |
63 | |
64 | @Override |
65 | public String toString() { |
66 | return "comparator " + name; |
67 | } |
68 | |
69 | |
70 | } |
71 | |
72 | @Override |
73 | public Map<String, Object> createAccessee() { |
74 | return new TreeMap<String, Object>(new UidComparator(elementAccess.toString())); |
75 | } |
76 | |
77 | @Override |
78 | public CompositeParam getParam(int i) { |
79 | if ((i < 0) || (i >= map.size())) { |
80 | return null; |
81 | } |
82 | return Param.build().id(Integer.toString(i)).forAccess(elementAccess).finish(CompositeParam.class); |
83 | } |
84 | |
85 | @Override |
86 | public CompositeParam getParam(String id) { |
87 | Integer i = Numbers.parse(id, Integer.class); |
88 | if (i != null) { |
89 | return getParam(i); |
90 | } |
91 | Integer uidNumber = getUidNumber(id); |
92 | if (uidNumber == null) { |
93 | return null; |
94 | } |
95 | if (!map.containsKey(id)) { |
96 | return null; |
97 | } |
98 | return Param.build().id(id).forAccess(elementAccess).finish(CompositeParam.class); |
99 | } |
100 | |
101 | @Override |
102 | public String getId() { |
103 | return "l " + elementAccess.getId() + " " + uidName; |
104 | } |
105 | |
106 | @Override |
107 | public int getParamCount() { |
108 | return map.size(); |
109 | } |
110 | |
111 | @Override |
112 | public <T> T get(int i, Class<T> type) { |
113 | Iterator<Map.Entry<String, Object>> iterator = map.entrySet().iterator(); |
114 | while (i > 0 && iterator.hasNext()) { |
115 | iterator.next(); |
116 | --i; |
117 | } |
118 | if (i > 0) { |
119 | return null; |
120 | } |
121 | if (!iterator.hasNext()) { |
122 | return null; |
123 | } |
124 | return Casting.tryCast(type, iterator.next().getValue()); |
125 | } |
126 | |
127 | @Override |
128 | public <T> T get(String id, Class<T> type) { |
129 | Integer i = Numbers.parse(id, Integer.class); |
130 | if (i != null) { |
131 | return get(i, type); |
132 | } |
133 | Integer uidNumber = getUidNumber(id); |
134 | if (uidNumber == null) { |
135 | return null; |
136 | } |
137 | return Casting.tryCast(type, map.get(id)); |
138 | } |
139 | |
140 | @Override |
141 | public <T> T get(ValueParam param, Class<T> type) { |
142 | return get(param.getId(), type); |
143 | } |
144 | |
145 | public String getUidOf(Object value) { |
146 | Object tmp = elementAccess.getSelected(); |
147 | elementAccess.select(value); |
148 | String uid = elementAccess.get(uidName, String.class); |
149 | elementAccess.select(tmp); |
150 | if (uid == null) { |
151 | return null; |
152 | } |
153 | return uid; |
154 | } |
155 | |
156 | protected int setByUid(Object object, String uid) { |
157 | if (uid == null) { |
158 | uid = getUidOf(object); |
159 | if (uid == null) { |
160 | log.error("failed to set - missing uid"); |
161 | return 0; |
162 | } |
163 | } |
164 | if (object == null) { |
165 | map.remove(uid); |
166 | } else { |
167 | map.put(uid, object); |
168 | } |
169 | return 0; |
170 | } |
171 | |
172 | @Override |
173 | public <T> int set(int i, T value) { |
174 | throw new UnsupportedOperationException().msg("accesing unique list through index"); |
175 | } |
176 | |
177 | @Override |
178 | public <T> int set(String id, T value) { |
179 | Integer i = Numbers.parse(id, Integer.class); |
180 | if (i != null) { |
181 | return set(i, value); |
182 | } |
183 | if (value == null) { |
184 | return setByUid(null, id); |
185 | } |
186 | String uid = getUidOf(value); |
187 | if (uid != null && id != null) { |
188 | if (!id.equals(uid)) { |
189 | log.error("uid mismatch with set key"); |
190 | return 0; |
191 | } |
192 | setByUid(value, uid); |
193 | return 0; |
194 | } |
195 | if (uid != null) { |
196 | setByUid(value, uid); |
197 | return 0; |
198 | } |
199 | if (id != null) { |
200 | setByUid(value, id); |
201 | return 0; |
202 | } |
203 | log.error("missing both uid and id - failed to set"); |
204 | return 0; |
205 | } |
206 | |
207 | @Override |
208 | public <T> int set(ValueParam param, T value) { |
209 | return set(param.getId(), value); |
210 | } |
211 | |
212 | @Override |
213 | public void clearValues() { |
214 | map.clear(); |
215 | } |
216 | |
217 | @SuppressWarnings("unchecked") |
218 | @Override |
219 | public UniqueListAccess select(Object object) { |
220 | assert (object instanceof Map); |
221 | map = (Map<String, Object>) object; |
222 | return this; |
223 | } |
224 | |
225 | @Override |
226 | public Object getSelected() { |
227 | return map; |
228 | } |
229 | |
230 | @Override |
231 | public UniqueListAccess cloneAccess() { |
232 | return new UniqueListAccess(elementAccess.cloneAccess(), uidName); |
233 | } |
234 | |
235 | @Override |
236 | public String computeIdentifierFor(Object selected) { |
237 | String uid = getUidOf(selected); |
238 | if (uid == null) { |
239 | log.error("missing uid field"); |
240 | return null; |
241 | } |
242 | return uid; |
243 | } |
244 | |
245 | @Override |
246 | public Iterable<Param> getParams() { |
247 | return new Iterable<Param>() { |
248 | |
249 | @Override |
250 | public Iterator<Param> iterator() { |
251 | return new Iterator<Param>() { |
252 | |
253 | protected Iterator<Map.Entry<String, Object>> internal = map.entrySet().iterator(); |
254 | |
255 | @Override |
256 | public boolean hasNext() { |
257 | return internal.hasNext(); |
258 | } |
259 | |
260 | @Override |
261 | public Param next() { |
262 | return Param.build().id(internal.next().getKey()).forAccess(elementAccess).finish(); |
263 | } |
264 | |
265 | @Override |
266 | public void remove() { |
267 | throw new UnimplementedException().msg("remove element from list").arg("list", UniqueListAccess.this); |
268 | |
269 | } |
270 | }; |
271 | } |
272 | }; |
273 | } |
274 | |
275 | @Override |
276 | public int getCompositeParamCount() { |
277 | return map.size(); |
278 | } |
279 | |
280 | @Override |
281 | public CompositeParam getCompositeParam(int number) { |
282 | return getParam(number); |
283 | } |
284 | } |
Note: See TracBrowser
for help on using the repository browser.