/* * Cooperative Systems */ package src.coop; import jade.domain.FIPAAgentManagement.Property; import jade.content.lang.Codec; import jade.content.lang.xml.*; import jade.content.onto.Ontology; import jade.content.onto.OntologyException; import jade.content.*; import jade.core.AID; import jade.core.Agent; import jade.core.behaviours.Behaviour; import jade.core.behaviours.CyclicBehaviour; import jade.content.lang.Codec.CodecException; import jade.core.behaviours.OneShotBehaviour; import jade.domain.DFService; import jade.domain.FIPAAgentManagement.DFAgentDescription; import jade.domain.FIPAAgentManagement.ServiceDescription; import jade.domain.FIPAException; import jade.lang.acl.ACLMessage; import jade.lang.acl.MessageTemplate; import jade.util.leap.List; import java.util.ArrayList; import java.util.HashMap; import java.util.LinkedList; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; /** * Implementation of the Workplace Agent * @author Rudolf Mühlbauer, Aurel Wildfellner */ public class WorkplaceAgent extends Agent { // which resources were already delivered to the workplace? private Map<String, Integer> availableResources; // the queue of the items to produce private LinkedList<ProductionPlan> toProduce = null; // what is currently being produced private ProductionPlan currentProductionPlan = null; private Codec codec = new XMLCodec(); private Ontology ontology = BiFabOntology.getInstance(); // the message handling behaviour Behaviour readMessages = new CyclicBehaviour(this) { @Override public void action() { // filtering the messages also hides "FAILURE" messages, // disabled for debugging MessageTemplate mt = MessageTemplate.and( MessageTemplate.MatchLanguage(codec.getName()), MessageTemplate.MatchOntology(ontology.getName())); ACLMessage msg = receive(); if (msg != null) { try { ContentElement ce = null; // decode the message if (msg.getPerformative() == ACLMessage.QUERY_IF) { ce = getContentManager().extractContent(msg); if (ce instanceof ProductionPlan) { ProductionPlan p = (ProductionPlan) ce; System.out.println("WorkplaceAgent " + getLocalName() + " received production plan for: " + p.id + "/" + p.getCount()); onSetProductionPlan(p); } else if (ce instanceof Delivered) { onDelivered((Delivered) ce); } else { System.out.println("WorkplaceAgent " + getLocalName() + " received unexpected, " + ce.toString()); } } else { System.out.println("WorkplaceAgent " + getLocalName() + " received non-INFORM"); } } catch (CodecException ce) { ce.printStackTrace(); } catch (OntologyException oe) { oe.printStackTrace(); } } else { block(); } } }; @Override protected void setup() { toProduce = new LinkedList<ProductionPlan>(); availableResources = new HashMap<String, Integer>(); getContentManager().registerLanguage(codec); getContentManager().registerOntology(ontology); Object[] args = getArguments(); String product = ""; if (args != null && args.length == 1) { product = "" + args[0]; } else { System.out.println(getLocalName() + " must have arguments"); System.exit(1); } //Register the book-selling service in the yellow pages DFAgentDescription dfd = new DFAgentDescription(); dfd.setName(getAID()); ServiceDescription sd = new ServiceDescription(); sd.setType("Workplace"); sd.setName(getLocalName() + "Workplace"); sd.addProperties(new Property("Product", product)); dfd.addServices(sd); try { DFService.register(this, dfd); } catch (FIPAException fe) { fe.printStackTrace(); } System.out.println("WorkplaceAgent: created for " + product); addBehaviour(readMessages); } private void checkCompleted() throws CodecException, OntologyException { // check if the product can be produced with the current availables boolean complete = true; List resources = currentProductionPlan.getResources(); // check if needs are satisfied for (int i = 0; i < resources.size(); i++) { Resource r = (Resource) resources.get(i); if (!availableResources.containsKey(r.getId())) { complete = false; break; } int availCount = availableResources.get(r.getId()); if (r.getCount() > availCount) { complete = false; break; } } // debug output for (int i = 0; i < resources.size(); i++) { Resource r = (Resource) resources.get(i); int availCount = availableResources.get(r.getId()); System.out.println("WorkplaceAgent " + getLocalName() + " has " + availCount + " of " + r.getId() + " and needs " + r.getCount()); } if (complete) { // update available-counts for (int i = 0; i < resources.size(); i++) { Resource r = (Resource) resources.get(i); int availCount = availableResources.get(r.getId()); availableResources.put(r.getId(), availCount - r.getCount()); } // inform the storage that this item is finished setCompleted(); } } private void onSetProductionPlan(ProductionPlan ce) throws CodecException, OntologyException { // enqueue a productionplan for every "count" for (int i = 0; i < ce.getCount(); i++) { toProduce.add(ce); } // process whole productionplan while (!toProduce.isEmpty()) { currentProductionPlan = toProduce.removeLast(); List resources = currentProductionPlan.getResources(); if (resources == null) { // this is a buy-request since it does not build anything. // this is by convention. setCompleted(); } else { // this is a construction request. analyze requirements // and produce when parts are ready. for (int i = 0; i < resources.size(); i++) { Resource r = (Resource) resources.get(i); System.out.println("WorkplaceAgent " + getLocalName() + " needs: " + r.getId() + "/" + r.getCount() + " from storage"); // initially non quantities of the resource are available availableResources.put(r.getId(), 0); RequestResource requestRes = new RequestResource(r.getId(), r.getCount()); requestRes.setRequester(getAID()); ACLMessage requestMsg = new ACLMessage(ACLMessage.QUERY_IF); requestMsg.addReceiver(new AID("Storage", false)); requestMsg.setLanguage(codec.getName()); requestMsg.setOntology(ontology.getName()); getContentManager().fillContent(requestMsg, requestRes); send(requestMsg); } checkCompleted(); } } } private void onDelivered(Delivered ce) throws CodecException, OntologyException { String id = ce.getResource(); int deliveredCount = ce.getCount(); System.out.println("WorkplaceAgent " + getLocalName() + " received: " + id + "/" + deliveredCount + " from logistics"); // update available resources to new counts if (availableResources.containsKey(id)) { int availCount = availableResources.get(id); availableResources.put(id, availCount + deliveredCount); } // see if the product can already be built checkCompleted(); } private void setCompleted() throws CodecException, OntologyException { // a little delay to make simulation more pretty try { Thread.sleep(100); } catch (InterruptedException ex) { Logger.getLogger(WorkplaceAgent.class.getName()).log(Level.SEVERE, null, ex); } System.out.println("WorkplaceAgent " + getLocalName() + " completed: " + currentProductionPlan.id + " with " + toProduce.size() + " more to produce"); // send message to storage: completed! SetCompleted setCompleted = new SetCompleted(currentProductionPlan.id); ACLMessage requestMsg = new ACLMessage(ACLMessage.QUERY_IF); requestMsg.addReceiver(new AID("Storage", false)); requestMsg.setLanguage(codec.getName()); requestMsg.setOntology(ontology.getName()); getContentManager().fillContent(requestMsg, setCompleted); send(requestMsg); } }