package com.framsticks.hosting; import static com.framsticks.util.lang.Strings.assureNotEmpty; import com.framsticks.communication.*; import com.framsticks.communication.queries.ApplicationRequest; import com.framsticks.communication.queries.CallRequest; import com.framsticks.communication.queries.GetRequest; import com.framsticks.communication.queries.InfoRequest; import com.framsticks.communication.queries.SetRequest; import com.framsticks.core.Instance; import com.framsticks.core.InstanceUtils; import com.framsticks.core.Path; import com.framsticks.params.*; import com.framsticks.params.types.ProcedureParam; import com.framsticks.parsers.Savers; import com.framsticks.util.FramsticksException; import com.framsticks.util.dispatching.AbstractJoinable; import com.framsticks.util.dispatching.Dispatching; import com.framsticks.util.dispatching.Future; import com.framsticks.util.dispatching.Joinable; import com.framsticks.util.dispatching.JoinableParent; import com.framsticks.util.dispatching.JoinableState; import static com.framsticks.core.InstanceUtils.*; import java.net.Socket; import java.util.LinkedList; import java.util.List; /** * @author Piotr Sniegowski */ public class InstanceClient extends AbstractJoinable implements RequestHandler, JoinableParent { protected final Server server; protected final Instance instance; protected final ServerConnection connection; public InstanceClient(Server server, Socket socket) { this.server = server; this.instance = server.hosted; this.connection = new ServerConnection(socket, this); } @Override public String getName() { return connection + " to " + server; } @Override public void handle(final ApplicationRequest request, final ResponseCallback responseCallback) { assureNotEmpty(request.getPath()); resolve(instance, request.getPath(), new Future(responseCallback) { @Override protected void result(final Path path) { // final AccessInterface access = instance.prepareAccess(path); final AccessInterface access = instance.prepareAccess(path.getTop().getParam()); if (request instanceof SetRequest) { SetRequest set = (SetRequest) request; //TODO Proxy - here is break of chain, instance should have hosted //hosted set AccessInterface access2 = InstanceUtils.bindAccess(path); int flag = access2.set(set.getField(), set.getValue()); responseCallback.process(new Response(true, Flags.write(flag, null), null)); return; } if (request instanceof GetRequest) { InstanceUtils.findInfo(path, new Future(responseCallback) { @Override protected void result(FramsClass result) { if (result == null) { throw new FramsticksException().msg("failed to find info for access bind"); } List files = new LinkedList(); AccessInterface access = bindAccess(path); if (access == null) { throw new FramsticksException().msg("failed to bind access"); } ListSink sink = new ListSink(); access.save(sink); files.add(new File(path.getTextual(), new ListSource(sink.getOut()))); responseCallback.process(new Response(true, "", files)); } }); return; } if (request instanceof CallRequest) { final CallRequest callRequest = (CallRequest) request; instance.call(path, access.getFramsClass().getParamEntry(callRequest.getProcedure(), ProcedureParam.class), callRequest.getArguments().toArray(), new Future(responseCallback) { @Override protected void result(Object result) { ListSink sink = new ListSink(); sink.print("Result:").breakLine(); sink.print("value:").print("["); if (result != null) { sink.print(result); } sink.print("]"); responseCallback.process(new Response(true, "", File.single(new File("", new ListSource(sink.getOut()))))); } }); return; } if (request instanceof InfoRequest) { findInfo(path, new Future(responseCallback) { @Override protected void result(FramsClass result) { if (result == null) { throw new FramsticksException().msg("info not found"); } responseCallback.process(new Response(true, null, File.single(new File(path.getTextual(), new ListSource(Savers.saveFramsClass(new ListSink(), result).getOut()))))); } }); return; } throw new FramsticksException().msg("invalid request type: " + request.getCommand()); } }); } @Override protected void joinableStart() { Dispatching.use(connection, this); } @Override protected void joinableInterrupt() { Dispatching.drop(connection, this); } @Override protected void joinableFinish() { } @Override protected void joinableJoin() throws InterruptedException { Dispatching.join(connection); } @Override public void childChangedState(Joinable joinable, JoinableState state) { proceedToState(state); } }