source: java/main/src/main/java/com/framsticks/core/Path.java @ 96

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

HIGHLIGHTS:

  • cleanup Instance management
    • extract Instance interface
    • extract Instance common algorithms to InstanceUtils?
  • fix closing issues: Ctrl+C or window close button

properly shutdown whole program

by Java Framsticks framework

  • fix parsing and printing of all request types
  • hide exception passing in special handle method of closures
    • substantially improve readability of closures
    • basically enable use of exception in asynchronous closures

(thrown exception is transported back to the caller)

  • implement call request on both sides

CHANGELOG:
Further improve calling.

Improve instance calling.

Calling is working on both sides.

Improve exception handling in testing.

Waiters do not supercede other apllication exception being thrown.

Finished parsing and printing of all request types (with tests).

Move implementation and tests of request parsing to Request.

Add tests for Requests.

Improve waits in asynchronours tests.

Extract more algorithms to InstanceUtils?.

Extract Instance.resolve to InstanceUtils?.

Improve naming.

Improve passing exception in InstanceClient?.

Hide calling of passed functor in StateCallback?.

Hide Exception passing in asynchronous closures.

Hide exception passing in Future.

Make ResponseCallback? an abstract class.

Make Future an abstract class.

Minor change.

Move getPath to Path.to()

Move bindAccess to InstanceUtils?.

Extract common things to InstanceUtils?.

Fix synchronization bug in Connection.

Move resolve to InstanceUtils?.

Allow names of Joinable to be dynamic.

Add support for set request server side.

More fixes in communication.

Fix issues with parsing in connection.

Cut new line characters when reading.

More improvements.

Migrate closures to FramsticksException?.

Several changes.

Extract resolveAndFetch to InstanceUtils? algorithms.

Test resolving and fetching.

More fixes with function signature deduction.

Do not print default values in SimpleAbstractAccess?.

Add test of FramsClass? printing.

Improve FramsticksException? messages.

Add explicit dispatcher synchronization feature.

Rework assertions in tests.

Previous solution was not generic enough.

Allow addition of joinables to collection after start.

Extract SimulatorInstance? from RemoteInstance?.

Remove PrivateJoinableCollection?.

Improve connections.

Move shutdown hook to inside the Monitor.

It should work in TestNG tests, but it seems that
hooks are not called.

In ServerTest? client connects to testing server.

Move socket initialization to receiver thread.

Add proper closing on Ctrl+C (don't use signals).

Fix bugs with server accepting connections.

Merge Entity into Joinable.

Reworking ServerInstance?.

Extract more algorithm to InstanceUtils?.

Extract some common functionality from AbstractInstance?.

Functions were placed in InstanceUtils?.

Hide registry of Instance.

Use ValueParam? in Instance interface.

Minor change.

Extract Instance interface.

Old Instance is now AbstractInstance?.

File size: 6.7 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 Instance instance;
26        final String textual;
27        final LinkedList<Node> nodes;
28
29        protected static Object getKnownChild(Instance instance, AccessInterface access, CompositeParam param) {
30                Object child = access.get(param, Object.class);
31                if (child == null) {
32                        return null;
33                }
34                try {
35                        instance.prepareAccess(param);
36                        return child;
37                } catch (FramsticksException e) {
38                }
39                return null;
40        }
41
42        /**
43         * @param instance
44         * @param textual
45         * @param nodes
46         */
47        Path(Instance instance, String textual, LinkedList<Node> nodes) {
48                this.instance = instance;
49                this.textual = textual;
50                this.nodes = nodes;
51        }
52
53        public Path appendNode(Node node) {
54                assert isResolved();
55                return new PathBuilder().instance(instance).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(param, null));
61        }
62
63        public static class PathBuilder {
64
65                Instance instance;
66                String textual;
67                final LinkedList<Node> nodes = new LinkedList<Node>();
68
69                public Path finish() {
70                        assert instance != null;
71                        assert textual != null;
72                        return new Path(instance, textual, nodes);
73                }
74
75                public PathBuilder()
76                {
77                }
78
79                public PathBuilder instance(Instance instance) {
80                        this.instance = instance;
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.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                public PathBuilder resolve(@Nonnull Instance instance, String textual) {
133
134                        assert nodes.isEmpty();
135                        assert instance.isActive();
136                        this.instance = instance;
137
138                        nodes.add(instance.getRoot());
139                        Node current = instance.getRoot();
140
141                        StringBuilder b = new StringBuilder();
142                        Iterator<String> i = splitPath(textual);
143                        while (i.hasNext() && current.getObject() != null) {
144                                AccessInterface access = instance.prepareAccess(current.getParam());
145                                if (access == null) {
146                                        break;
147                                }
148                                String e = i.next();
149                                Param p = access.getParam(e);
150                                if (!(p instanceof CompositeParam)) {
151                                        //entries.add(new Entry());
152                                        break;
153                                }
154                                CompositeParam c = (CompositeParam)p;
155                                b.append("/").append(e);
156                                access.select(current.getObject());
157                                current = new Node(c, getKnownChild(instance, access, c));
158                                nodes.add(current);
159                        }
160                        this.textual = (nodes.size() == 1) ? "/" : b.toString();
161
162                        return this;
163                }
164        }
165
166        public static PathBuilder build() {
167                return new PathBuilder();
168        }
169
170        public Path appendResolution(Object object) {
171                assert !isResolved();
172                Path result = new PathBuilder().textual(textual).instance(instance).add(nodes).setLast(object).finish();
173                assert size() == result.size();
174                return result;
175        }
176
177        public final Object getTopObject() {
178                return getTop().getObject();
179        }
180
181        public final Node getTop() {
182                return nodes.getLast();
183        }
184
185        public final Node getUnder() {
186                assert nodes.size() >= 2;
187                return nodes.get(nodes.size() - 2);
188        }
189
190        public final String getTextual() {
191                return textual;
192        }
193
194        public String toString() {
195                return instance + textual + (!isResolved() ? "!" : "");
196        }
197
198        public final int size() {
199                assert Dispatching.isThreadSafe();
200                return nodes.size();
201        }
202
203        public final boolean isResolved() {
204                assert Dispatching.isThreadSafe();
205                return getTop().getObject() != null;
206        }
207
208        public final boolean isResolved(String textual) {
209                assert Dispatching.isThreadSafe();
210                return isTheSame(textual) && isResolved();
211        }
212
213        public final boolean isTheSame(String textual) {
214                assert Dispatching.isThreadSafe();
215                return this.textual.equals(textual);
216        }
217
218        public final @Nonnull Instance getInstance() {
219                assert Dispatching.isThreadSafe();
220                return instance;
221        }
222
223        public Path tryResolveIfNeeded() {
224                if (isResolved()) {
225                        return this;
226                }
227                return tryFindResolution();
228        }
229
230        /** Attach resolution at end, if available.
231         *
232         * @return Modified path, if resolution was available, this otherwise.
233         */
234        public Path tryFindResolution() {
235                assert instance.isActive();
236                assert !isResolved();
237                if (size() == 1) {
238                        return Path.build().resolve(instance, "/").finish();//appendResolution(instance.root.object);
239                }
240                Object child = getKnownChild(instance, InstanceUtils.bindAccess(instance, getUnder()), getTop().getParam());
241                if (child == null) {
242                        return this;
243                }
244                return appendResolution(child);
245        }
246
247        public boolean matches(Path p) {
248                assert Dispatching.isThreadSafe();
249                assert instance == p.instance;
250                Iterator<Node> a = nodes.iterator();
251                Iterator<Node> b = p.nodes.iterator();
252                while (a.hasNext() && b.hasNext()) {
253                        Node an = a.next();
254                        Node bn = b.next();
255                        if (an.object != bn.object) {
256                                return false;
257                        }
258                }
259                return a.hasNext() == b.hasNext();
260        }
261
262        public String getLastElement() {
263                return getTop().getParam().getId();
264        }
265
266        public final boolean isOwner(Instance instance) {
267                return this.instance == instance;
268        }
269
270        // public void setInstance(Instance instance) {
271        //      this.instance = instance;
272        // }
273
274        @SuppressWarnings("unchecked")
275        public
276        List<Node> getNodes() {
277                return ListUtils.unmodifiableList(nodes);
278        }
279
280        public void assureResolved() {
281                if (!isResolved()) {
282                        throw new FramsticksException().msg("path is not resolved").arg("path", this);
283                }
284        }
285
286        public static Path to(@Nonnull Instance instance, String textual) {
287                return Path.build().resolve(instance, textual).finish();
288        }
289}
290
Note: See TracBrowser for help on using the repository browser.