package jade.domain.introspection; import jade.core.Agent; import jade.core.behaviours.CyclicBehaviour; import jade.lang.acl.*; import jade.domain.FIPANames; import jade.content.ContentManager; import jade.content.onto.Ontology; import jade.content.onto.OntologyException; import jade.content.onto.basic.*; import jade.content.lang.Codec; import jade.content.lang.Codec.CodecException; import jade.content.lang.sl.SLCodec; import jade.util.leap.List; import jade.util.leap.ArrayList; import java.lang.reflect.*; import java.io.Serializable; public class IntrospectionServer extends CyclicBehaviour { private Codec codec; private Ontology onto; private MessageTemplate template; private static Class serializableClass; static { try { serializableClass = Class.forName("java.io.Serializable"); } catch (Exception e) { } } public IntrospectionServer(Agent a) { super(a); } public void onStart() { ContentManager cm = myAgent.getContentManager(); onto = IntrospectionOntology.getInstance(); cm.registerOntology(onto); codec = cm.lookupLanguage(FIPANames.ContentLanguage.FIPA_SL); if (codec == null) { codec = cm.lookupLanguage(FIPANames.ContentLanguage.FIPA_SL2); if (codec == null) { codec = cm.lookupLanguage(FIPANames.ContentLanguage.FIPA_SL1); if (codec == null) { codec = cm.lookupLanguage(FIPANames.ContentLanguage.FIPA_SL0); } } } if (codec == null) { codec = new SLCodec(); cm.registerLanguage(codec); } template = MessageTemplate.and( MessageTemplate.MatchOntology(onto.getName()), MessageTemplate.MatchPerformative(jade.lang.acl.ACLMessage.REQUEST) ); } public void action() { jade.lang.acl.ACLMessage request = myAgent.receive(template); if (request != null) { try { ContentManager cm = myAgent.getContentManager(); Action actionExpr = (Action) cm.extractContent(request); Object act = actionExpr.getAction(); if (act instanceof GetKeys) { serveGetKeys(request, actionExpr, (GetKeys) act); } else if (act instanceof GetValue) { serveGetValue(request, actionExpr, (GetValue) act); } else { serveUnknownAction(request, actionExpr, act); } } catch (OntologyException oe) { reply(request, jade.lang.acl.ACLMessage.NOT_UNDERSTOOD); oe.printStackTrace(); } catch (CodecException ce) { reply(request, jade.lang.acl.ACLMessage.NOT_UNDERSTOOD); ce.printStackTrace(); } catch (ValueEncodingException vee) { jade.lang.acl.ACLMessage msg = request.createReply(); msg.setPerformative(jade.lang.acl.ACLMessage.FAILURE); msg.setContent("VALUE_NOT_ENCODABLE"); myAgent.send(msg); } catch (Throwable t) { reply(request, jade.lang.acl.ACLMessage.FAILURE); t.printStackTrace(); } } else { block(); } } protected void reply(jade.lang.acl.ACLMessage request, int performative) { jade.lang.acl.ACLMessage msg = request.createReply(); msg.setPerformative(performative); myAgent.send(msg); } protected void serveGetKeys(jade.lang.acl.ACLMessage request, Action aExpr, GetKeys action) throws Exception { List keys = new ArrayList(); Method[] mm = myAgent.getClass().getMethods(); for (int i = 0; i < mm.length; ++i) { Method method = mm[i]; if (method.getName().startsWith("get") && method.getParameterTypes().length == 0) { Class retType = method.getReturnType(); if (retType.isPrimitive() || (serializableClass != null && serializableClass.isAssignableFrom(retType))) { String key = method.getName().substring(3); keys.add(key); } } } Result r = new Result(aExpr, keys); jade.lang.acl.ACLMessage reply = request.createReply(); myAgent.getContentManager().fillContent(reply, r); reply.setPerformative(jade.lang.acl.ACLMessage.INFORM); myAgent.send(reply); } protected void serveGetValue(jade.lang.acl.ACLMessage request, Action aExpr, GetValue action) throws Exception { Method method = myAgent.getClass().getMethod("get"+action.getKey(), new Class[]{}); Object value = method.invoke(myAgent, (Object[]) null); if (value == null) { value = "null"; } Result r = new Result(aExpr, value); jade.lang.acl.ACLMessage reply = request.createReply(); try { myAgent.getContentManager().fillContent(reply, r); reply.setPerformative(jade.lang.acl.ACLMessage.INFORM); myAgent.send(reply); } catch (OntologyException oe) { throw new ValueEncodingException(); } catch (CodecException ce) { throw new ValueEncodingException(); } } protected void serveUnknownAction(jade.lang.acl.ACLMessage request, Action aExpr, Object action) { reply(request, jade.lang.acl.ACLMessage.REFUSE); } private class ValueEncodingException extends Exception { } }