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

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

HIGHLIGHTS:

CHANGELOG:
Get data also on tree expansion.

Use nice framstick icon for empty nodes.

Update panel after reload if it is current.

Add shallow reload procedure.

Cut Gui prefix from several tree classes.

Bring back counter of GuiTreeNode?.

Use IdentityHashMap? were it is more appriopriate.

Remove TreeListener?.

Do not use TreeListener? in GUI.

Minor change.

Done migration to GuiTreeModel?.

BrowserTest? in that version always crashes frams.linux.

Move rendering implementation into GuiAbstractNode?.

Use hand-crafted list in GuiTreeNode?.

Generally, it would be a great place for WeakIdentityHashMap?
(but there is none in Java Collection Framework).

Remove superfluous logging.

Fix bug in GuiTreeNode?.

Use IdentityHashMap? instead of HashMap?.

Improve structure update.

Filter out invalid uids in UniqueListAccess?.

Improve TreeCellRenderer?.

Add filtering in TrackConsole?.

Improve TreeModel?.

More changes.

More improvements.

More changes.

Remove TreeNode?.

Support MetaNode? in the GuiTreeModel?.

Implement more in GuiTreeModel?.

Add CompositeParam? interface to FramsClass? and AccessInterface?.

Allow access by number to UniqueList?.

Add UidComparator?.

Use TreeMap? as a default accessee in unique list.

It keeps order of keys.

Introduce classes to use with new TreeModel?.

Another step.

Migrate from TreeNode? to Node in many places.

Remove some uses of TreeNode? as DefaultMutableTreeNode?.

Remove Path from TreeNode? interface.

Remove Path from TreeNode?.

Add Path recration from node feature.

Reworking TreeCellRenderer?.

Minor change of TreeOperations? interface.

Remove last methods from TreeNode?.

Another minor step.

Do not store reference to TreeAtFrame? in TreeNode?.

Add proxy exceptionHandler to StatusBar?.

Move panels management to TreeAtFrame?.

Store localChanges in the NodeAtFrame?.

More cleanup.

Move name computing to TreeCellRenderer?.

Move tooltip and icon computations to TreeCellRenderer?.

More dispatches removed.

Remove most dispatching from TreeNode?.

TreeNode? does not actually redispatch tasks.

Make Tree embedded in Browser use SwingDispatcher?.

Make lazy binding of Tree with Dispatcher.

Minor changes.

Organizational change in AbstractTree?.

Make AbstractTree? compose from Thread instead of inherit from it.

Make SwingDispatcher? and AtOnceDispatcher? Joinable compatible.

Add ListPanelProvider?.

Improve Controls readonly and enabled handling.

Properly pass ExceptionHandlers? in more places.

Make Tree.get accept ValueParam?.

  • This is to allow access number of list elements.

Remove not needed get redirection in ClientAtServer?.

Rename tryResolve to tryGet.

Unify tryResolveAndGet into tryResolve.

Remove resolveTop from Tree interface.

Make Tree.get accept Future<Path>.

Use get to implement resolveTop also in ObjectTree?.

Unify resolveTop and get in RemoteTree?.

Another minor step.

More minor changes in tree operations.

Minor organizational changes.

In RemoteTree? first fetch info for root.

Reworking resolving.

Minor changes.

Make ListAccess? return proxy iterators (instead of creating temporary collection).

Let AccessInterface? return Iterable<Param>.

Improve resolving.

More improvements.

First working completion in ManagedConsole?.

Rename resolve to resolveTop.

This reflects the actuall functionality.

Change semantic of tryResolve and tryResolveAndGet.

File size: 5.9 KB
Line 
1package com.framsticks.params;
2
3import com.framsticks.util.FramsticksException;
4import com.framsticks.util.UnimplementedException;
5import com.framsticks.util.UnsupportedOperationException;
6import com.framsticks.util.lang.Casting;
7import com.framsticks.util.lang.Numbers;
8import org.apache.log4j.Logger;
9
10import java.util.*;
11
12/**
13 * @author Piotr Sniegowski
14 */
15public 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.