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

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

HIGHLIGHTS:

  • add auto loading and saving algorithms between

frams files format and Java classes

  • respect ValueChange? events in GUI (do not reload object)
  • support results of procedures in Java server
  • make Experiment automatically convert between frams file and NetFile? object
  • add MessageLogger? (compatible with original frams server messages)
  • WorkPackageLogic? now validates results, is able to discard them, reschedule

whole package, or only uncomputed remainder

CHANGELOG:
Show just a short description in PrimeExperiment?.

Add primes_changed event to the PrimeExperiment?.

Make WorkPackageLogic? robust to frams server returning invalid results.

Add MessageLogger? to logics.

Add NetFile? interface. Support Messages from server.

Minor changes to connections.

Merge results in the PrimeExperiment?.

More netload class->file conversion to Simulator.

Move netsave parsing to Simulator.

Fix bug with inverted ordering of events firing in Experiment.

Minor changes.

Minor logging changes.

Use AccessOperations?.convert in NetLoadSaveLogic?

NetLoadSaveLogic? now encloses the conversion.

Use more generic AccessOperations? saveAll and loadAll in PrimePackage?.

Add Result class for enclosing of call invocations' results.

Improve feature request handling in Connections.

Use AccessOperations?.convert in RemoteTree? events parsing.

Minor change.

Add some information params to Java server root and CLI objects.

A draft implementation of loadAll algorithm.

That algorithm tries to load objects into a tree structure.

Add AccessOperationsTest? test.

Develop WorkPackageLogic?.

  • add state tracking fields
  • add work package generation

Add utility class SimplePrimitive?.

Meant for Java backend classes, enclose a single primitive value
and set of listeners.

Improve primitive value refresh in GUI.

When ValueChange? found in called event, do not reload whole
object, but only update GUI (no communication is performed).

Use ValueChange? in the TestClass? test.

Minor changes.

Sending all packages in PrimeExperiment? to the frams servers.

Develop AccessOperations?.loadComposites().

Remove addAccess from MultiParamLoader? interface.

There is now no default AccessProvider? in MultiParamLoader?.
User must explicitely set AccessStash? or Registry.

Improve saving algorithms in AccessOperations?.

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 getId() {
143                return "l " + elementAccess.getId() + " " + 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.