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

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

HIGHLIGHTS:

  • improve tree side notes
  • improve GUI layout
  • add foldable list of occured events to EventControl?
  • improve automatic type conversion in proxy listeners
  • implement several Access functionalities as algorithms independent of Access type
  • introduce draft base classes for distributed experiments
  • automatically register dependant Java classes to FramsClass? registry
  • add testing prime experiment and configuration
  • simplify and improve task dispatching

CHANGELOG:
Improve task dispatching in RemoteTree?.

GUI no longer hangs on connection problems.

Make all dispatchers joinables.

Refactorize Thread dispatcher.

Remove Task and PeriodicTask?.

Use Java utilities in those situations.

Reworking tasks dispatching.

Fix bug in EventControl? listener dispatching.

Minor improvements.

Add testing configuration for ExternalProcess? in GUI.

More improvement to prime.

Support for USERREADONLY in GUI.

Add that flag to various params in Java classes.

Remove redundant register clauses from several FramsClassAnnotations?.

Automatically gather and register dependant classes.

Add configuration for prime.

Improve Simulator class.

Add prime.xml configuration.

Introduce draft Experiment and Simulator classes.

Add prime experiment tests.

Enclose typical map with listeners into SimpleUniqueList?.

Needfile works in GUI.

Improve needfile handling in Browser.

More improvement with NeedFile?.

Implementing needfile.

Update test.

Rename ChangeEvent? to TestChangeEvent?.

Automatic argument type search in RemoteTree? listeners.

MultiParamLoader? uses AccessProvider?. By default old implementation
enclosed in AccessStash? or Registry.

Minor changes.

Rename SourceInterface? to Source.

Also improve toString of File and ListSource?.

Remove unused SimpleSource? class.

Add clearing in HistoryControl?.

Show entries in table at EventControl?.

Improve EventControl?.

Add listeners registration to EventControl?.

Add foldable table to HistoryControl?.

Add control row to Procedure and Event controls.

Improve layout of controls.

Another minor change to gui layout.

Minor improvement in the SliderControl?.

Minor changes.

Move ReflectionAccess?.Backend to separate file.

It was to cluttered.

Cleanup in ReflectionAccess?.

Move setMin, setMax, setDef to AccessOperations?.

Extract loading operation into AccessOperations?.

Append Framsticks to name of UnsupportedOperationException?.

The java.lang.UnsupportedOperationException? was shadowing this class.

Rename params.Util to params.ParamsUtil?.

Several improvements.

Minor changes.

Implement revert functionality.

Improve local changes management.

Minor improvement.

Remove methods rendered superfluous after SideNoteKey? improvement.

Improve SideNoteKey?.

It is now generic type, so explicit type specification at
call site is no more needed.

Introduce SideNoteKey? interface.

Only Objects implementing that key may be used as side note keys.

Minor improvements.

Use strings instead of ValueControls? in several gui mappings.

File size: 6.8 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                throw new FramsticksUnsupportedOperationException().msg("accesing unique list through index");
208        }
209
210        @Override
211        public <T> int set(String id, T value) {
212                Integer i = Numbers.parse(id, Integer.class);
213                if (i != null) {
214                        return set(i, value);
215                }
216                if (value == null) {
217                        return setByUid(null, id);
218                }
219                String uid = getUidOf(value);
220                if (uid != null && id != null) {
221                        if (!id.equals(uid)) {
222                                log.error("uid mismatch with set key");
223                                return 0;
224                        }
225                        setByUid(value, uid);
226                        return 0;
227                }
228                if (uid != null) {
229                        setByUid(value, uid);
230                        return 0;
231                }
232                if (id != null) {
233                        setByUid(value, id);
234                        return 0;
235                }
236                log.error("missing both uid and id - failed to set");
237                return 0;
238        }
239
240        @Override
241        public <T> int set(ValueParam param, T value) {
242                return set(param.getId(), value);
243        }
244
245        @Override
246        public void clearValues() {
247                map.clear();
248        }
249
250        @SuppressWarnings("unchecked")
251        @Override
252        public UniqueListAccess select(Object object) {
253                map = ParamsUtil.selectObjectForAccess(this, object, Map.class);
254                return this;
255        }
256
257        @Override
258        public Object getSelected() {
259                return map;
260        }
261
262        @Override
263        public UniqueListAccess cloneAccess() {
264                return new UniqueListAccess(elementAccess.cloneAccess(), uidName);
265        }
266
267        // public String computeIdentifierFor(Object selected) {
268        //      String uid = getUidOf(selected);
269        //      if (uid == null) {
270        //              log.error("missing uid field");
271        //              return null;
272        //      }
273        //      return uid;
274        // }
275
276        @Override
277        public Iterable<Param> getParams() {
278                return new Iterable<Param>() {
279
280                        @Override
281                        public Iterator<Param> iterator() {
282                                return new Iterator<Param>() {
283
284                                        protected Iterator<Map.Entry<String, Object>> internal = map.entrySet().iterator();
285
286                                        @Override
287                                        public boolean hasNext() {
288                                                return internal.hasNext();
289                                        }
290
291                                        @Override
292                                        public Param next() {
293                                                return paramBuilder.id(internal.next().getKey()).finish();
294                                        }
295
296                                        @Override
297                                        public void remove() {
298                                                throw new UnimplementedException().msg("remove element from list").arg("list", UniqueListAccess.this);
299
300                                        }
301                                };
302                        }
303                };
304        }
305
306        @Override
307        public int getCompositeParamCount() {
308                return map.size();
309        }
310
311        @Override
312        public CompositeParam getCompositeParam(int number) {
313                return getParam(number);
314        }
315
316        @Override
317        public ParamBuilder buildParam(ParamBuilder builder) {
318                return builder.name(containedTypeName + " list").type(UniqueListParam.class).containedTypeName(containedTypeName).uid(uidName);
319        }
320
321}
Note: See TracBrowser for help on using the repository browser.