/** * {@inheritDoc} * * @see com.corona.context.InjectMethod#invoke(com.corona.context.ContextManager, * java.lang.Object) */ @SuppressWarnings({"unchecked", "rawtypes"}) @Override public Object invoke(final ContextManager contextManager, final Object component) { // find server by server name from current context and make sure it is defined Server server = contextManager.get(Server.class, this.serverName); if (server == null) { this.logger.error( "Server [{0}] isn't registered in context, should define it first", this.serverName); throw new ValueException( "Server [{0}] isn't registered in context, should define it first", this.serverName); } // transform client input stream into request object ServerRequest request = null; try { request = this.getRequest(contextManager, server); } catch (RemoteException e) { this.logger.error( "Fail to open client input stream or transform stream to server request object", e); return new ServerInternalErrorResponse( server, "Fail to get server request object: " + e.getMessage()); } // execute producing method according to client request and return it in order to create server // response try { switch (request.getCode()) { case Constants.REQUEST.EXECUTE: Object outcome = this.execute(component, (ServerExecuteRequest) request); if (outcome != null) { return new ServerExecutedResponse( server, server.getToken(((ServerExecuteRequest) request).getToken()), this.getMarshaller(), outcome); } else { return new ServerExecutedResponse( server, server.getToken(((ServerExecuteRequest) request).getToken()), null, null); } case Constants.REQUEST.LOGIN: if (server.isSupportedVersion(((ServerLoginRequest) request).getClientLibraryVersion())) { String token = this.login(component, (ServerLoginRequest) request); if (token != null) { return new ServerLoggedInResponse(server, token); } else { return new ServerCantLoggedInResponse( server, "Invalid user name or password to log in"); } } else { return new ServerCantLoggedInResponse(server, "Client libray version is not supported"); } case Constants.REQUEST.LOGOUT: this.logout(component, (ServerLogoutRequest) request); return new ServerLoggedOutResponse(server); default: return new ServerInvalidActionResponse( server, ((ServerInvalidActionRequest) request).getInvalidCode()); } } catch (Exception e) { return new ServerFailExecuteResponse(server, e); } }
/** * @param contextManager the current context manager * @param server the server * @return the request * @throws RemoteException if fail to translate stream to request object */ private ServerRequest getRequest(final ContextManager contextManager, final Server server) throws RemoteException { // get input stream from InputStream input; try { input = contextManager.get(HttpServletRequest.class).getInputStream(); input = new GZIPInputStream(input); } catch (IOException e) { this.logger.error("Fail to open client servlet request as GZIP input stream", e); throw new RemoteException("Fail to open client servlet request as GZIP input stream", e); } // read identifier and check whether this identifier is valid or not int identifier; try { identifier = input.read(); } catch (IOException e) { this.logger.error("Fail to read identifier from client input stream", e); throw new RemoteException("Fail to read identifier from client input stream", e); } if (identifier == -1) { this.logger.error("Should can read identifier but client input stream is empty"); throw new RemoteException("Should can read identifier but client input stream is empty"); } else if (((byte) identifier) != Constants.IDENTIFIER) { this.logger.error("Invalid identifier [{0}] read from client input stream", identifier); throw new RemoteException( "Invalid identifier [{0}] read from client input stream", identifier); } // read action code and make sure it is read from client stream int action; try { action = input.read(); } catch (IOException e) { this.logger.error("Fail to read action code from client input stream", e); throw new RemoteException("Fail to read action code from client input stream", e); } if (action == -1) { this.logger.error("Should can read action code but client input stream is empty"); throw new RemoteException("Should can read action code but client input stream is empty"); } // create request according to action code ServerRequest request; switch (action) { case Constants.REQUEST.EXECUTE: request = new ServerExecuteRequest(server, this.getUnmarshaller()); break; case Constants.REQUEST.LOGIN: request = new ServerLoginRequest(server); break; case Constants.REQUEST.LOGOUT: request = new ServerLogoutRequest(server); break; default: request = new ServerInvalidActionRequest(server, (byte) action); break; } // read request specified data from client input stream request.read(input); return request; }