source: java/main/src/main/java/com/framsticks/core/Path.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: 6.8 KB
Line 
1package com.framsticks.core;
2
3import com.framsticks.params.AccessInterface;
4import com.framsticks.params.CompositeParam;
5import com.framsticks.params.Param;
6import com.framsticks.util.FramsticksException;
7import com.framsticks.util.dispatching.Dispatching;
8
9import java.util.Iterator;
10import java.util.LinkedList;
11import java.util.List;
12
13import javax.annotation.Nonnull;
14import javax.annotation.concurrent.Immutable;
15
16import org.apache.commons.collections.ListUtils;
17
18/**
19 * @author Piotr Sniegowski
20 */
21@Immutable
22public final class Path {
23        // private final static Logger log = Logger.getLogger(Path.class.getName());
24
25        final Tree tree;
26        final String textual;
27        final LinkedList<Node> nodes;
28
29        protected static Object getKnownChild(Tree tree, AccessInterface access, CompositeParam param) {
30                Object child = access.get(param, Object.class);
31                if (child == null) {
32                        return null;
33                }
34                try {
35                        tree.prepareAccess(param);
36                        return child;
37                } catch (FramsticksException e) {
38                }
39                return null;
40        }
41
42        /**
43         * @param tree
44         * @param textual
45         * @param nodes
46         */
47        Path(Tree tree, String textual, LinkedList<Node> nodes) {
48                this.tree = tree;
49                this.textual = textual;
50                this.nodes = nodes;
51        }
52
53        public Path appendNode(Node node) {
54                assert isResolved();
55                return new PathBuilder().tree(tree).textual(textual + ((size() == 1) ? "" : "/") + node.getParam().getId()).add(nodes).add(node).finish();
56        }
57
58        public Path appendParam(CompositeParam param) {
59                assert isResolved();
60                return appendNode(new Node(tree, param, null));
61        }
62
63        public static class PathBuilder {
64
65                Tree tree;
66                String textual;
67                final LinkedList<Node> nodes = new LinkedList<Node>();
68
69                public Path finish() {
70                        assert tree != null;
71                        assert textual != null;
72                        return new Path(tree, textual, nodes);
73                }
74
75                public PathBuilder()
76                {
77                }
78
79                public PathBuilder tree(Tree tree) {
80                        this.tree = tree;
81                        return this;
82                }
83
84                public PathBuilder textual(String textual) {
85                        this.textual = textual;
86                        return this;
87                }
88
89                public PathBuilder add(List<Node> nodes) {
90                        this.nodes.addAll(nodes);
91                        return this;
92                }
93
94                public PathBuilder add(Node node) {
95                        this.nodes.add(node);
96                        return this;
97                }
98
99                public PathBuilder setLast(Object object) {
100                        Node n = nodes.pollLast();
101                        nodes.add(new Node(n.getTree(), n.getParam(), object));
102                        return this;
103                }
104
105                public PathBuilder buildUpTo(List<Node> nodes, Node node) {
106                        StringBuilder b = new StringBuilder();
107                        boolean add = false;
108                        for (Node n : nodes) {
109                                this.nodes.add(n);
110                                if (add) {
111                                        b.append("/").append(n.getParam().getId());
112                                }
113                                add = true;
114                                if (n == node) {
115                                        break;
116                                }
117                        }
118                        this.textual = (nodes.size() == 1) ? "/" : b.toString();
119                        return this;
120                }
121
122                public static Iterator<String> splitPath(String path) {
123                        List<String> list = new LinkedList<String>();
124                        for (String s : path.split("/")) {
125                                if (!s.isEmpty()) {
126                                        list.add(s);
127                                }
128                        }
129                        return list.iterator();
130                }
131
132
133                public PathBuilder resolve(@Nonnull Tree tree, String textual) {
134
135                        assert nodes.isEmpty();
136                        assert tree.isActive();
137                        this.tree = tree;
138
139                        Node current = tree.getAssignedRoot();
140                        nodes.add(current);
141
142                        StringBuilder b = new StringBuilder();
143                        Iterator<String> i = splitPath(textual);
144                        while (i.hasNext() && current.getObject() != null) {
145                                AccessInterface access = TreeOperations.bindAccess(current);// tree.prepareAccess(current.getParam());
146                                String e = i.next();
147                                Param p = access.getParam(e);
148                                if (!(p instanceof CompositeParam)) {
149                                        //entries.add(new Entry());
150                                        break;
151                                }
152                                CompositeParam c = (CompositeParam)p;
153                                b.append("/").append(e);
154                                access.select(current.getObject());
155                                current = new Node(current.getTree(), c, getKnownChild(tree, access, c));
156                                nodes.add(current);
157                        }
158                        this.textual = (nodes.size() == 1) ? "/" : b.toString();
159
160                        return this;
161                }
162        }
163
164        public static PathBuilder build() {
165                return new PathBuilder();
166        }
167
168        public Path appendResolution(Object object) {
169                assert !isResolved();
170                Path result = new PathBuilder().textual(textual).tree(tree).add(nodes).setLast(object).finish();
171                assert size() == result.size();
172                return result;
173        }
174
175        public final Object getTopObject() {
176                return getTop().getObject();
177        }
178
179        public final Node getTop() {
180                return nodes.getLast();
181        }
182
183        public final Node getUnder() {
184                assert nodes.size() >= 2;
185                return nodes.get(nodes.size() - 2);
186        }
187
188        public final String getTextual() {
189                return textual;
190        }
191
192        public String toString() {
193                return tree + textual + (!isResolved() ? "!" : "");
194        }
195
196        public String getFullTextual() {
197                return tree.getName() + textual;
198        }
199
200        public final int size() {
201                assert Dispatching.isThreadSafe();
202                return nodes.size();
203        }
204
205        public final boolean isResolved() {
206                assert Dispatching.isThreadSafe();
207                return getTop().getObject() != null;
208        }
209
210        public final boolean isResolved(String textual) {
211                assert Dispatching.isThreadSafe();
212                return isTheSame(textual) && isResolved();
213        }
214
215        public final boolean isTheSame(String textual) {
216                assert Dispatching.isThreadSafe();
217                return this.textual.equals(textual);
218        }
219
220        public final boolean isTheSameTextually(Path path) {
221                assert Dispatching.isThreadSafe();
222                return (tree == path.getTree()) && textual.equals(path.getTextual());
223        }
224
225        public final @Nonnull Tree getTree() {
226                assert Dispatching.isThreadSafe();
227                return tree;
228        }
229
230        public Path tryResolveIfNeeded() {
231                if (isResolved()) {
232                        return this;
233                }
234                return tryFindResolution();
235        }
236
237        /** Attach resolution at end, if available.
238         *
239         * @return Modified path, if resolution was available, this otherwise.
240         */
241        public Path tryFindResolution() {
242                assert tree.isActive();
243                assert !isResolved();
244                if (size() == 1) {
245                        return Path.build().resolve(tree, "/").finish();
246                }
247                Object child = getKnownChild(tree, TreeOperations.bindAccess(getUnder()), getTop().getParam());
248                if (child == null) {
249                        return this;
250                }
251                return appendResolution(child);
252        }
253
254
255        public String getLastElement() {
256                return getTop().getParam().getId();
257        }
258
259        public final boolean isOwner(Tree tree) {
260                return this.tree == tree;
261        }
262
263        @SuppressWarnings("unchecked")
264        public
265        List<Node> getNodes() {
266                return ListUtils.unmodifiableList(nodes);
267        }
268
269        public Path assureResolved() {
270                if (!isResolved()) {
271                        throw new FramsticksException().msg("path is not resolved").arg("path", this);
272                }
273                return this;
274        }
275
276        public static Path to(@Nonnull Tree tree, String textual) {
277                return Path.build().resolve(tree, textual).finish();
278        }
279
280        public boolean isTheSameObjects(Path path) {
281                if (tree != path.getTree()) {
282                        return false;
283                }
284                if (size() != path.size()) {
285                        return false;
286                }
287                if (!getTextual().equals(path.getTextual())) {
288                        return false;
289                }
290                Iterator<Node> a = nodes.iterator();
291                Iterator<Node> b = path.getNodes().iterator();
292                while (a.hasNext()) {
293                        assert b.hasNext();
294                        if (a.next() != b.next()) {
295                                return false;
296                        }
297                }
298                return true;
299        }
300
301
302        // public boolean isEmpty() {
303        //      return nodes.isEmpty();
304        // }
305}
306
Note: See TracBrowser for help on using the repository browser.