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

Last change on this file since 193 was 193, checked in by Maciej Komosinski, 10 years ago

Set svn:eol-style native for all textual files

  • Property svn:eol-style set to native
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.