package context.arch.service; import context.arch.comm.DataObject; import context.arch.comm.CommunicationsHandler; import context.arch.storage.Attributes; import context.arch.service.helper.FunctionDescription; import context.arch.service.helper.ServiceInput; import context.arch.service.helper.FunctionDescriptions; import context.arch.handler.AsyncServiceHandler; import context.arch.MethodException; import context.arch.InvalidMethodException; /** * This class implements a generic inherited service. A service is inherited * by a server from a widget that it uses. It allows the server to act as * a proxy to widget services. * * @see context.arch.service.Service * @see context.arch.handler.AsyncServiceHandler */ public class InheritedService extends Service implements AsyncServiceHandler { private String serviceHost; private String servicePort; private String serviceId; @SuppressWarnings("unused") private String serverName; private String serviceName; /** * Basic constructor that creates an inherited service object. * * @param comm Object that implements the CommunicationsHandler interface * @param serverName Name of the server offering the inherited service * @param serviceName Name of the service being inherited * @param descriptions FunctionDescriptions for the inherited service * @param serviceHost Hostname of the component offering the original service * @param servicePort Port of the component offering the original service * @param serviceId Id of the component offering the original service */ public InheritedService(CommunicationsHandler comm, String serverName, String serviceName, FunctionDescriptions descriptions, String serviceHost, String servicePort, String serviceId) { super(comm,serverName+serviceName,descriptions); this.serviceHost = serviceHost; this.servicePort = servicePort; this.serviceId = serviceId; this.serviceName = serviceName; this.serverName = serverName; } /** * Basic constructor that creates an inherited service object. * * @param comm Object that implements the CommunicationsHandler interface * @param serverName Name of the server offering the inherited service * @param serviceName Name of the service being inherited * @param descriptions FunctionDescriptions for the inherited service * @param serviceHost Hostname of the component offering the original service * @param servicePort Port of the component offering the original service * @param serviceId Id of the component offering the original service */ public InheritedService(CommunicationsHandler comm, String serverName, String serviceName, FunctionDescriptions descriptions, String serviceHost, int servicePort, String serviceId) { super(comm,serverName+serviceName,descriptions); this.serviceHost = serviceHost; this.servicePort = Integer.toString(servicePort); this.serviceId = serviceId; this.serviceName = serviceName; this.serverName = serverName; } /** * This method is called when a component requests that this inherited service * be executed. It checks to see whether the service is synchronous or * asynchronous and then calls the inherited service. If the service is * asynchronous, it adds the request to its pending queue. * * @param serviceInput Object containing all information required to execute the service * @return result of the service request * @see CommunicationsHandler#executeSynchronousWidgetService(String,int,String,String,String,AttributeNameValues) * @see CommunicationsHandler#executeAsynchronousWidgetService(AsyncServiceHandler,String,int,String,String,String,AttributeNameValues,String) * @see context.arch.service.helper.PendingOut#addPending(ServiceInput) */ public DataObject execute(ServiceInput serviceInput) { String timing = getFunctionDescriptions().getFunctionDescription(serviceInput.getFunctionName()).getSynchronicity(); if (timing.equals(FunctionDescription.FUNCTION_SYNC)) { // replace name; not sure why --Brian serviceInput.setServiceName(serviceName); return comm.executeSynchronousWidgetService(serviceHost,Integer.parseInt(servicePort),serviceId, //serviceName,serviceInput.getFunctionName(),serviceInput.getInput() serviceInput); } else if (timing.equals(FunctionDescription.FUNCTION_ASYNC)) { pending.addPending(serviceInput); return comm.executeAsynchronousWidgetService(this,serviceHost,Integer.parseInt(servicePort),serviceId, serviceName,serviceInput.getFunctionName(),serviceInput.getInput(), serviceInput.getUniqueId()); } return new DataObject(); } /** * This method is called when this inherited asynchronous service returns * the result. It collects the returned data, determines which requester * the data should go to, removes the request from the pending queue and * sends the data to the requester. * * @param requestTag Unique id to identify the request * @param data DataObject containing the service results * @return Always returns null * * @exception MethodException thrown if the asynchronous service result can't be handled successfully * @exception InvalidMethodException thrown if the asynchronous service result * was not expected and can't be routed correctly * @see Service#sendServiceResult(ServiceInput,AttributeNameValues) * @see context.arch.service.helper.PendingOut#removePending(String) */ public DataObject asynchronousServiceHandle(String requestTag, DataObject data) throws MethodException, InvalidMethodException { Attributes atts = Attributes.fromDataObject(data); ServiceInput si = pending.getPending(requestTag); pending.removePending(requestTag); @SuppressWarnings("unused") DataObject data2 = sendServiceResult(si,atts); return null; } }