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

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

HIGHLIGTS:

  • complete events implementation
  • add CLI in Java Framsticks server
  • add automatic registration for events in GUI
  • improve objects fetching (object are never overwritten with new instances)
  • properly react for ListChange? events
  • add ListPanel? with table view
    • columns to be shown may be statically specified in configuration
    • currently modyfying data through tables is not available
  • improve maven configuration
    • configuration file may be specified without touching pom.xml

CHANGELOG:
Extract constants from Flags into ParamFlags? and SetStateFlags?.

Extract flags I/O to FlagsUtils? class.

Configured maven to exec given resource configuration.

For example:
mvn exec:exec -Dframsticks.config=/configs/managed-console.xml

Cleanup pom.xml

Rename ObjectTree? to LocalTree? (also make LocalTree? and RemoteTree? final).

Minor change.

Add maximum number of columns in ListPanelProvider?.

Improve ColumnsConfig? interpretation.

Automatically fill FramsClass?.name if trying to construct empty.

Improve identitifer case mangling in XmlLoader?.

Introduce configurable ColumnsConfig?.

Draft working version of ListPanel?.

Table is being shown (although empty).

More improvements to table building.

Move some functionality from Frame to TreeModel?.

Move tree classes in gui to separate package.

Remove old table related classes.

Add draft implementation of TableModel?.

Redirect ParamBuilder?.forAccess to AccessInterface?.

Optimize ParamBuilder?.forAccess()

Do not clear list when loading.

Do not load fetched values directly.

Implement different AccessInterface? copying policy.

Optimize fetching values routine.

Remove Mode enum (work out get semantics).

Some improvements to ListChange? handling.

Improve UniqueListAccess?.

Add reaction for ListChanges? in the TreeNode?.

EventListeners? are being added in the TreeNode?.

Listeners for ListParams? are now very naive (they download
whole list).

Automatially register on events in GUI.

Events are working in RemoteTree? and Server.

Move listeners to the ClientSideManagedConnection?.

Remove old classes responsible for event subscriptions.

Improve event reading.

Improve events handling at server side.

Add register attribute in FramsClassAnnotation?
to automatically also register other classes.

Registering events works.

Setup for remote listeners registration.

More improvements.

Minor changes.

Add rootTree to the ClientAtServer?.

Moving CLI to the ClientAtServer?.

Fix bug: use Void.TYPE instead of Void.class

More development around CLI.

  • Improve Path resolving.

Add synthetic root to ObjectTree?.

It is needed to allow sybling for the original root
that would containg CLI.

Some work with registering events in RemoteTree?.

Draft implementation of listener registering in RemoteTree?.

Support events registration in the ObjectTree?.

Add events support to ReflectionAccess?.

EventParam? is recognized by ParamCandidate?.

Prepare interface for Events across project.

Add EventListener? and API for listeners in Tree.

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