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

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

HIGHLIGHTS:

  • add SimultorProviders? hierarchy
  • start Framsticks server over SSH
  • FJF compatible with Framsticks 4.0rc3
  • reading and writing of standard.expt
  • a proof-of-concept implementation of StandardExperiment?

CHANGELOG:
Optionally return FreeAccess? from registry.

Add SimulatorRange?.

StandardExperiment? with genotypes circulation.

Automate registration around StandardState?.

More improvements to StandardExperiment?.

Skeleton version of StandardExperiment?.

Test saving of StandardState?.

Standard experiment state is being loaded.

More development towards StandardState? reading.

Work on reading standard experiment state.

Add classes for standard experiment.

Update example standard.expt

Add FreeAccess? and FreeObject?.

Made compatible with version 4.0rc3

Change deserialization policy.

Improve SSH support.

Working running simulator over SSH.

Fix joining bug in Experiment.

Working version of SimulatorRunner?.

Add more SimulatorProviders?.

Working PrimeExperimentTest? with 4.0rc3

Add references to deserialization.

Add OpaqueObject? and it's serialization.

Add deserialization of dictionaries.

Partial implementation of deserialization.

Add more tests for deserialization.

Prepare tests for deserialization.

Add proper result to prime experiment test.

Minor fixes to simulators providers.

Draft version of SimulatorProvider?.

Add SimulatorProvider? interface.

File size: 7.6 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        public int setUidOf(Object value, String uid) {
190                return uidAccess.select(value).set(uidName, uid);
191        }
192
193        protected int uidCounter = 1;
194
195        public String generateNextUid() {
196                return containedTypeName.substring(0, 1).toUpperCase() + Integer.toString(uidCounter++);
197        }
198
199        public String findNextFreeUid() {
200                String uid;
201                do {
202                        uid = generateNextUid();
203                } while (get(uid, Object.class) != null);
204                return uid;
205        }
206
207        protected int setByUid(Object object, String uid) {
208                if (uid == null) {
209                        uid = getUidOf(object);
210                        if (uid == null) {
211                                uid = findNextFreeUid();
212                                setUidOf(object, uid);
213                        }
214                }
215                if (object == null) {
216                        map.remove(uid);
217                } else {
218                        map.put(uid, object);
219                }
220                return 0;
221        }
222
223        @Override
224        public <T> int set(int i, T value) {
225                if (value != null) {
226                        if (i != map.size()) {
227                                throw new FramsticksUnsupportedOperationException().msg("setting element in unique list through index is available only for addition");
228                        }
229                        set(getUidOf(value), value);
230                        return 0;
231                }
232                if (i >= map.size()) {
233                        throw new FramsticksUnsupportedOperationException().msg("invalid index for removal");
234                }
235                Object current = get(i, Object.class);
236                return setByUid(null, getUidOf(current));
237        }
238
239        @Override
240        public <T> int set(String id, T value) {
241                if (id == null) {
242                        return setByUid(value, null);
243                }
244                Integer i = Numbers.parse(id, Integer.class);
245                if (i != null) {
246                        return set(i, value);
247                }
248                if (value == null) {
249                        return setByUid(null, id);
250                }
251                String uid = getUidOf(value);
252                if (uid != null && id != null) {
253                        if (!id.equals(uid)) {
254                                log.error("uid mismatch with set key");
255                                return 0;
256                        }
257                        setByUid(value, uid);
258                        return 0;
259                }
260                if (uid != null) {
261                        setByUid(value, uid);
262                        return 0;
263                }
264                if (id != null) {
265                        setByUid(value, id);
266                        return 0;
267                }
268                log.error("missing both uid and id - failed to set");
269                return 0;
270        }
271
272        @Override
273        public <T> int set(ValueParam param, T value) {
274                return set(param.getId(), value);
275        }
276
277        @Override
278        public void clearValues() {
279                map.clear();
280        }
281
282        @SuppressWarnings("unchecked")
283        @Override
284        public UniqueListAccess select(Object object) {
285                map = ParamsUtil.selectObjectForAccess(this, object, Map.class);
286                return this;
287        }
288
289        @Override
290        public Object getSelected() {
291                return map;
292        }
293
294        @Override
295        public UniqueListAccess cloneAccess() {
296                return new UniqueListAccess(elementAccess.cloneAccess(), uidName);
297        }
298
299        // public String computeIdentifierFor(Object selected) {
300        //      String uid = getUidOf(selected);
301        //      if (uid == null) {
302        //              log.error("missing uid field");
303        //              return null;
304        //      }
305        //      return uid;
306        // }
307
308        @Override
309        public Iterable<Param> getParams() {
310                return new Iterable<Param>() {
311
312                        @Override
313                        public Iterator<Param> iterator() {
314                                return new Iterator<Param>() {
315
316                                        protected Iterator<Map.Entry<String, Object>> internal = map.entrySet().iterator();
317
318                                        @Override
319                                        public boolean hasNext() {
320                                                return internal.hasNext();
321                                        }
322
323                                        @Override
324                                        public Param next() {
325                                                return paramBuilder.id(internal.next().getKey()).finish();
326                                        }
327
328                                        @Override
329                                        public void remove() {
330                                                throw new UnimplementedException().msg("remove element from list").arg("list", UniqueListAccess.this);
331
332                                        }
333                                };
334                        }
335                };
336        }
337
338        @Override
339        public int getCompositeParamCount() {
340                return map.size();
341        }
342
343        @Override
344        public CompositeParam getCompositeParam(int number) {
345                return getParam(number);
346        }
347
348        @Override
349        public ParamBuilder buildParam(ParamBuilder builder) {
350                return builder.name(containedTypeName + " list").type(UniqueListParam.class).containedTypeName(containedTypeName).uid(uidName);
351        }
352
353}
Note: See TracBrowser for help on using the repository browser.