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

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

HIGHLIGTS:

  • complete events implementation
  • add CLI in Java Framsticks server
  • add automatic registration for events in GUI
  • improve objects fetching (object are never overwritten with new instances)
  • properly react for ListChange? events
  • add ListPanel? with table view
    • columns to be shown may be statically specified in configuration
    • currently modyfying data through tables is not available
  • improve maven configuration
    • configuration file may be specified without touching pom.xml

CHANGELOG:
Extract constants from Flags into ParamFlags? and SetStateFlags?.

Extract flags I/O to FlagsUtils? class.

Configured maven to exec given resource configuration.

For example:
mvn exec:exec -Dframsticks.config=/configs/managed-console.xml

Cleanup pom.xml

Rename ObjectTree? to LocalTree? (also make LocalTree? and RemoteTree? final).

Minor change.

Add maximum number of columns in ListPanelProvider?.

Improve ColumnsConfig? interpretation.

Automatically fill FramsClass?.name if trying to construct empty.

Improve identitifer case mangling in XmlLoader?.

Introduce configurable ColumnsConfig?.

Draft working version of ListPanel?.

Table is being shown (although empty).

More improvements to table building.

Move some functionality from Frame to TreeModel?.

Move tree classes in gui to separate package.

Remove old table related classes.

Add draft implementation of TableModel?.

Redirect ParamBuilder?.forAccess to AccessInterface?.

Optimize ParamBuilder?.forAccess()

Do not clear list when loading.

Do not load fetched values directly.

Implement different AccessInterface? copying policy.

Optimize fetching values routine.

Remove Mode enum (work out get semantics).

Some improvements to ListChange? handling.

Improve UniqueListAccess?.

Add reaction for ListChanges? in the TreeNode?.

EventListeners? are being added in the TreeNode?.

Listeners for ListParams? are now very naive (they download
whole list).

Automatially register on events in GUI.

Events are working in RemoteTree? and Server.

Move listeners to the ClientSideManagedConnection?.

Remove old classes responsible for event subscriptions.

Improve event reading.

Improve events handling at server side.

Add register attribute in FramsClassAnnotation?
to automatically also register other classes.

Registering events works.

Setup for remote listeners registration.

More improvements.

Minor changes.

Add rootTree to the ClientAtServer?.

Moving CLI to the ClientAtServer?.

Fix bug: use Void.TYPE instead of Void.class

More development around CLI.

  • Improve Path resolving.

Add synthetic root to ObjectTree?.

It is needed to allow sybling for the original root
that would containg CLI.

Some work with registering events in RemoteTree?.

Draft implementation of listener registering in RemoteTree?.

Support events registration in the ObjectTree?.

Add events support to ReflectionAccess?.

EventParam? is recognized by ParamCandidate?.

Prepare interface for Events across project.

Add EventListener? and API for listeners in Tree.

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