package jadex.base.service.remote;
import jadex.base.fipa.SFipa;
import jadex.bridge.ComponentTerminatedException;
import jadex.bridge.MessageType;
import jadex.commons.concurrent.DefaultResultListener;
import jadex.commons.service.SServiceProvider;
import jadex.commons.service.clock.IClockService;
import jadex.commons.service.library.ILibraryService;
import jadex.micro.IMicroExternalAccess;
import jadex.micro.MicroAgent;
import jadex.xml.reader.Reader;
import jadex.xml.writer.Writer;
import java.util.Map;
/**
* Remote service management service that hosts the corresponding
* service. It basically has the task to forward messages from
* remote service management components on other platforms to its service.
*/
public class RemoteServiceManagementAgent extends MicroAgent
{
//-------- attributes --------
/** The remote management service. */
protected RemoteServiceManagementService rms;
//-------- constructors --------
/**
* Called once after agent creation.
*/
public void agentCreated()
{
SServiceProvider.getService(getServiceProvider(), IClockService.class)
.addResultListener(createResultListener(new DefaultResultListener()
{
public void resultAvailable(Object source, Object result)
{
final IClockService clock = (IClockService)result;
SServiceProvider.getService(getServiceProvider(), ILibraryService.class)
.addResultListener(createResultListener(new DefaultResultListener()
{
public void resultAvailable(Object source, Object result)
{
final ILibraryService libservice = (ILibraryService)result;
rms = new RemoteServiceManagementService((IMicroExternalAccess)getExternalAccess(), clock, libservice);
addDirectService(rms);
}
}));
}
}));
}
// /**
// * Execute the functional body of the agent.
// * Is only called once.
// */
// public void executeBody()
// {
// ICommand gcc = new ICommand()
// {
// public void execute(Object args)
// {
// System.gc();
// waitFor(5000, this);
// }
// };
// waitFor(5000, gcc);
// }
/**
* Called just before the agent is removed from the platform.
* @return The result of the component.
*/
public void agentKilled()
{
// Send notifications to other processes that remote references are not needed any longer.
rms.getRemoteReferenceModule().shutdown();
}
/**
* Called, whenever a message is received.
* @param msg The message.
* @param mt The message type.
*/
public void messageArrived(final Map msg, final MessageType mt)
{
if(SFipa.MESSAGE_TYPE_NAME_FIPA.equals(mt.getName()))
{
SServiceProvider.getService(getServiceProvider(), ILibraryService.class)
.addResultListener(createResultListener(new DefaultResultListener()
{
public void resultAvailable(Object source, Object result)
{
// Hack!!! Manual decoding for using custom class loader.
final ILibraryService ls = (ILibraryService)result;
Object content = msg.get(SFipa.CONTENT);
if(content instanceof String)
{
// Catch decode problems.
// Should be ignored or be a warning.
try
{
// content = JavaReader.objectFromXML((String)content, ls.getClassLoader());
content = Reader.objectFromXML(rms.getReader(), (String)content, ls.getClassLoader());
}
catch(Exception e)
{
content = null;
// getLogger().warning("Remote service management service could not decode message."+content);
}
}
if(content instanceof IRemoteCommand)
{
final IRemoteCommand com = (IRemoteCommand)content;
com.execute((IMicroExternalAccess)getExternalAccess(), rms).addResultListener(createResultListener(new DefaultResultListener()
{
public void resultAvailable(Object source, Object result)
{
// System.out.println("result of command: "+com+" "+result);
if(result!=null)
{
final Object repcontent = result;
createReply(msg, mt).addResultListener(createResultListener(new DefaultResultListener()
{
public void resultAvailable(Object source, Object result)
{
Map reply = (Map)result;
// reply.put(SFipa.CONTENT, JavaWriter.objectToXML(repcontent, ls.getClassLoader()));
String content = Writer.objectToXML(rms.getWriter(), repcontent, ls.getClassLoader(), msg.get(SFipa.SENDER));
reply.put(SFipa.CONTENT, content);
// System.out.println("content: "+content);
sendMessage(reply, mt);
}
public void exceptionOccurred(Object source, Exception exception)
{
// Terminated, when rms killed in mean time
if(!(exception instanceof ComponentTerminatedException))
{
super.exceptionOccurred(source, exception);
}
}
}));
}
}
public void exceptionOccurred(Object source, Exception exception)
{
// Terminated, when rms killed in mean time
if(!(exception instanceof ComponentTerminatedException))
{
super.exceptionOccurred(source, exception);
}
}
}));
}
else if(content!=null)
{
getLogger().warning("RMS unexpected message content: "+content);
}
}
}));
}
}
}