source: java/main/src/main/java/com/framsticks/hosting/ClientAtServer.java @ 103

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

HIGHLIGHTS:

  • add auto loading and saving algorithms between

frams files format and Java classes

  • respect ValueChange? events in GUI (do not reload object)
  • support results of procedures in Java server
  • make Experiment automatically convert between frams file and NetFile? object
  • add MessageLogger? (compatible with original frams server messages)
  • WorkPackageLogic? now validates results, is able to discard them, reschedule

whole package, or only uncomputed remainder

CHANGELOG:
Show just a short description in PrimeExperiment?.

Add primes_changed event to the PrimeExperiment?.

Make WorkPackageLogic? robust to frams server returning invalid results.

Add MessageLogger? to logics.

Add NetFile? interface. Support Messages from server.

Minor changes to connections.

Merge results in the PrimeExperiment?.

More netload class->file conversion to Simulator.

Move netsave parsing to Simulator.

Fix bug with inverted ordering of events firing in Experiment.

Minor changes.

Minor logging changes.

Use AccessOperations?.convert in NetLoadSaveLogic?

NetLoadSaveLogic? now encloses the conversion.

Use more generic AccessOperations? saveAll and loadAll in PrimePackage?.

Add Result class for enclosing of call invocations' results.

Improve feature request handling in Connections.

Use AccessOperations?.convert in RemoteTree? events parsing.

Minor change.

Add some information params to Java server root and CLI objects.

A draft implementation of loadAll algorithm.

That algorithm tries to load objects into a tree structure.

Add AccessOperationsTest? test.

Develop WorkPackageLogic?.

  • add state tracking fields
  • add work package generation

Add utility class SimplePrimitive?.

Meant for Java backend classes, enclose a single primitive value
and set of listeners.

Improve primitive value refresh in GUI.

When ValueChange? found in called event, do not reload whole
object, but only update GUI (no communication is performed).

Use ValueChange? in the TestClass? test.

Minor changes.

Sending all packages in PrimeExperiment? to the frams servers.

Develop AccessOperations?.loadComposites().

Remove addAccess from MultiParamLoader? interface.

There is now no default AccessProvider? in MultiParamLoader?.
User must explicitely set AccessStash? or Registry.

Improve saving algorithms in AccessOperations?.

File size: 8.1 KB
Line 
1package com.framsticks.hosting;
2
3import static com.framsticks.util.lang.Strings.assureNotEmpty;
4
5import com.framsticks.communication.*;
6import com.framsticks.communication.queries.ApplicationRequest;
7import com.framsticks.communication.queries.CallRequest;
8import com.framsticks.communication.queries.GetRequest;
9import com.framsticks.communication.queries.InfoRequest;
10import com.framsticks.communication.queries.RegisterRequest;
11import com.framsticks.communication.queries.SetRequest;
12import com.framsticks.core.LocalTree;
13import com.framsticks.core.Tree;
14import com.framsticks.core.Path;
15import com.framsticks.params.*;
16import com.framsticks.params.types.EventParam;
17import com.framsticks.params.types.ProcedureParam;
18import com.framsticks.parsers.Savers;
19import com.framsticks.util.FramsticksException;
20import com.framsticks.util.Misc;
21import com.framsticks.util.dispatching.AbstractJoinable;
22import com.framsticks.util.dispatching.Dispatching;
23import com.framsticks.util.dispatching.ExceptionResultHandler;
24import com.framsticks.util.dispatching.FutureHandler;
25import com.framsticks.util.dispatching.Joinable;
26import com.framsticks.util.dispatching.JoinableParent;
27import com.framsticks.util.dispatching.JoinableState;
28import com.framsticks.util.lang.FlagsUtil;
29import com.framsticks.util.lang.Strings;
30
31import static com.framsticks.core.TreeOperations.*;
32import static com.framsticks.params.AccessOperations.*;
33
34import java.net.Socket;
35
36/**
37 * @author Piotr Sniegowski
38 */
39public class ClientAtServer extends AbstractJoinable implements RequestHandler, JoinableParent, ExceptionResultHandler {
40
41        protected final Server server;
42        protected final Tree contentTree;
43        protected final Object treeRootObject;
44        protected final ServerSideManagedConnection connection;
45
46        protected final Cli cliObject;
47        protected final LocalTree rootTree;
48
49
50        protected final FramsClass rootFramsClass;
51        protected final Object root;
52        protected final String contentPrefix;
53
54        public ClientAtServer(Server server, Socket socket) {
55                this.server = server;
56                this.contentTree = server.hosted;
57                this.connection = new ServerSideManagedConnection(socket, this);
58
59                treeRootObject = contentTree.getAssignedRoot().getObject();
60                Misc.throwIfNull(treeRootObject);
61
62                cliObject = new Cli(this);
63                rootTree = new LocalTree();
64                rootTree.setName(server.getName() + " root tree");
65                // rootTree.setDispatcher(new AtOnceDispatcher<Tree>());
66                rootTree.setDispatcher(server.getHosted().getDispatcher());
67                assert rootTree.getDispatcher() != null;
68
69                final FramsClass framsClass = bindAccess(contentTree.getAssignedRoot()).getFramsClass();
70                final String id = Strings.uncapitalize(framsClass.getName());
71                contentPrefix = "/" + id;
72                final String rootFramsClassId = id + "Root";
73
74                rootFramsClass = FramsClass.build()
75                        .idAndName(rootFramsClassId)
76                        .param(Param.build().id(id).name(framsClass.getName()).type("o " + framsClass.getId()))
77                        .param(Param.build().id("cli").name("CLI").type("o Cli"))
78                        .param(Param.build().id("system").name("Operating system").type("s").flags(ParamFlags.READONLY))
79                        .param(Param.build().id("user").name("User name").type("s").flags(ParamFlags.READONLY))
80                        .finish();
81
82                // rootTree.putInfoIntoCache(rootFramsClass);
83                rootTree.getRegistry().putFramsClass(rootFramsClass);
84                rootTree.getRegistry().registerAndBuild(Cli.class);
85                rootTree.getRegistry().registerAndBuild(CliEvent.class);
86
87                Access access = new PropertiesAccess(rootFramsClass);
88
89                root = createAccessee(rootTree, access);
90                access.select(root);
91                access.set(id, treeRootObject);
92                access.set("cli", cliObject);
93                access.set("system", System.getProperties().getProperty("os.name") + " " + System.getProperties().getProperty("os.version") + " " + System.getProperties().getProperty("os.arch"));
94                access.set("user", System.getProperties().getProperty("user.name"));
95
96                rootTree.assignRootParam(access.buildParam(new ParamBuilder()).name(rootFramsClassId).finish(CompositeParam.class));
97                rootTree.assignRootObject(root);
98
99        }
100
101        @Override
102        public String getName() {
103                return connection + " to " + server;
104        }
105
106        @Override
107        public void handle(final ApplicationRequest request, final ServerSideResponseFuture responseCallback) {
108                assureNotEmpty(request.getPath());
109
110                if (request.getPath().startsWith(contentPrefix)) {
111                        String p = request.getPath().substring(contentPrefix.length());
112                        request.path(p.equals("") ? "/" : p);
113                        handleInTree(contentTree, request, responseCallback, contentPrefix);
114                        return;
115                }
116
117                handleInTree(rootTree, request, responseCallback, "");
118        }
119
120        public static File printToFile(String path, Access access) {
121                ListSink sink = new ListSink();
122                save(access, sink);
123                return new File(path, new ListSource(sink.getOut()));
124        }
125
126        protected void handleInTree(final Tree tree, final ApplicationRequest request, final ServerSideResponseFuture responseCallback, final String usedPrefix) {
127
128                tryGet(tree, request.getActualPath(), new FutureHandler<Path>(responseCallback) {
129                        @Override
130                        protected void result(final Path path) {
131
132                                if (!path.getTextual().equals(request.getActualPath())) {
133                                        throw new FramsticksException().msg("invalid path").arg("path", request.getActualPath());
134                                }
135
136                                // final Access access = tree.prepareAccess(path);
137                                final Access access = bindAccess(path);
138
139                                if (request instanceof GetRequest) {
140                                        Object result = path.getTopObject();
141                                        if (result != access.getSelected()) {
142                                                throw new FramsticksException().msg("mismatch objects during fetch").arg("path", path);
143                                        }
144                                        responseCallback.pass(new Response(true, "", File.single(printToFile(path.getTextual(), access))));
145
146                                        return;
147                                }
148
149                                if (request instanceof SetRequest) {
150                                        SetRequest setRequest = (SetRequest) request;
151                                        tree.set(path, access.getFramsClass().getParamEntry(setRequest.getField(), PrimitiveParam.class), setRequest.getValue(), new FutureHandler<Integer>(responseCallback) {
152                                                @Override
153                                                protected void result(Integer flag) {
154                                                        responseCallback.pass(new Response(true, FlagsUtil.write(SetStateFlags.class, flag, null), null));
155
156                                                }
157                                        });
158                                        return;
159                                }
160
161                                if (request instanceof CallRequest) {
162                                        final CallRequest callRequest = (CallRequest) request;
163                                        tree.call(path, access.getFramsClass().getParamEntry(callRequest.getProcedure(), ProcedureParam.class), callRequest.getArguments().toArray(), Object.class, new FutureHandler<Object>(responseCallback) {
164                                                @Override
165                                                protected void result(Object result) {
166                                                        ListSink sink = new ListSink();
167                                                        sink.print("Result:").breakLine();
168                                                        sink.print("value:");
169                                                        sink.print("[");
170                                                        if (result != null) {
171                                                                sink.print(result);
172                                                        }
173                                                        sink.print("]");
174
175                                                        responseCallback.pass(new Response(true, "", File.single(new File("", new ListSource(sink.getOut())))));
176                                                }
177                                        });
178                                        return;
179                                }
180
181                                if (request instanceof InfoRequest) {
182                                        FramsClass framsClass = getInfo(path);
183                                        if (framsClass == null) {
184                                                throw new FramsticksException().msg("info should be available");
185                                        }
186                                        responseCallback.pass(new Response(true, null, File.single(new File(path.getTextual(), new ListSource(Savers.saveFramsClass(new ListSink(), framsClass).getOut())))));
187                                        return;
188                                }
189
190                                if (request instanceof RegisterRequest) {
191                                        RegisterRequest register = (RegisterRequest) request;
192
193                                        cliObject.addListener(path, access.getFramsClass().getParamEntry(register.getEventName(), EventParam.class), usedPrefix, responseCallback);
194                                        return;
195                                }
196
197                                throw new FramsticksException().msg("invalid request type: " + request.getCommand());
198                        }
199                });
200
201        }
202
203        @Override
204        protected void joinableStart() {
205                Dispatching.use(connection, this);
206                Dispatching.use(rootTree, this);
207        }
208
209        @Override
210        protected void joinableInterrupt() {
211                Dispatching.drop(rootTree, this);
212                Dispatching.drop(connection, this);
213        }
214
215        @Override
216        protected void joinableFinish() {
217
218        }
219
220        @Override
221        protected void joinableJoin() throws InterruptedException {
222                Dispatching.join(connection);
223                Dispatching.join(rootTree);
224        }
225
226        @Override
227        public void childChangedState(Joinable joinable, JoinableState state) {
228                proceedToState(state);
229        }
230
231        @Override
232        public void handle(FramsticksException exception) {
233                contentTree.handle(exception);
234        }
235
236        /**
237         * @return the tree
238         */
239        public Tree getTree() {
240                return contentTree;
241        }
242
243}
Note: See TracBrowser for help on using the repository browser.