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

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

HIGHLIGHTS:

  • import refactorization: move Tree, Path, etc.

from core to structure package

  • initial serialization implementation
  • improve PrimeExperiment? test
  • many organizational changes and convenience improvements

CHANGELOG:
Make registry in AbstractTree? final.

Move most classes from core to structure package.

Minor changes.

Switch names of Future and FutureHandler?.

Rename ExceptionResultHandler? to ExceptionHandler?.

Rename ExceptionHandler? to ExceptionDispatcherHandler?.

Fix bug in ParamCandidate? cache.

Add missing synchronization to the BufferedDispatcher?.

Develop @Serialized support.

Rework serialization further.

Add serialization/deserialization interface to ValueParam?.

Move getStorageType and isNumeric from Param down to params hierarchy.

Minor changes.

Improve param type induction.

Add TestSerializedClass? for testing new serialization.

Add info files gor GenePool? and Population.

Add standard.expt exemplary netfile.

Add type name field to PropertiesObject?.

Use PropertiesObject? for PropertiesAccess? instead of ordinary map.

Hide getFramsClass is several more places.

More unification accross FramsClass?, Access and Path.

Add ParamCollection?.

Simplify interface for getting params from FramsClass?, Access
or Path.

Make Access.call() interface variadic.

Add arguments(args) convenience wrapper around new Object[] {args}.

Upgrade to apache.commons.lang version 3.1

Minor improvement with Response constructors.

Develop proper result printing in ClientAtServer?.

Add experimentNetsave to PrimeExperiment?.

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