source: java/main/src/main/java/com/framsticks/params/UniqueListAccess.java @ 105

Last change on this file since 105 was 105, checked in by psniegowski, 11 years ago

HIGHLIGHTS:

  • import refactorization: move Tree, Path, etc.

from core to structure package

  • initial serialization implementation
  • improve PrimeExperiment? test
  • many organizational changes and convenience improvements

CHANGELOG:
Make registry in AbstractTree? final.

Move most classes from core to structure package.

Minor changes.

Switch names of Future and FutureHandler?.

Rename ExceptionResultHandler? to ExceptionHandler?.

Rename ExceptionHandler? to ExceptionDispatcherHandler?.

Fix bug in ParamCandidate? cache.

Add missing synchronization to the BufferedDispatcher?.

Develop @Serialized support.

Rework serialization further.

Add serialization/deserialization interface to ValueParam?.

Move getStorageType and isNumeric from Param down to params hierarchy.

Minor changes.

Improve param type induction.

Add TestSerializedClass? for testing new serialization.

Add info files gor GenePool? and Population.

Add standard.expt exemplary netfile.

Add type name field to PropertiesObject?.

Use PropertiesObject? for PropertiesAccess? instead of ordinary map.

Hide getFramsClass is several more places.

More unification accross FramsClass?, Access and Path.

Add ParamCollection?.

Simplify interface for getting params from FramsClass?, Access
or Path.

Make Access.call() interface variadic.

Add arguments(args) convenience wrapper around new Object[] {args}.

Upgrade to apache.commons.lang version 3.1

Minor improvement with Response constructors.

Develop proper result printing in ClientAtServer?.

Add experimentNetsave to PrimeExperiment?.

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