package src.coop;
import jade.domain.FIPAException;
import java.util.*;
import jade.content.ContentElement;
import jade.content.lang.Codec;
import jade.core.Agent;
import jade.core.behaviours.*;
import jade.content.onto.Ontology;
import jade.lang.acl.ACLMessage;
import jade.lang.acl.MessageTemplate;
import java.util.HashMap;
import java.util.Map;
import jade.content.lang.xml.*;
import jade.content.lang.Codec.CodecException;
import jade.content.onto.OntologyException;
import jade.core.AID;
import jade.util.leap.List;
import jade.domain.DFService;
import jade.domain.FIPAAgentManagement.DFAgentDescription;
import jade.domain.FIPAAgentManagement.ServiceDescription;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
*
* @author Rudolf Mühlbauer, Aurel Wildfellner
*/
public class StorageAgent extends Agent {
private Map<String, Integer> storage;
// queues for pending resource requests
private Map<RequestResource, AID> requestSenders;
private ArrayList<RequestResource> requestQueue;
private Codec codec = new XMLCodec();
private Ontology ontology = BiFabOntology.getInstance();
private java.util.List<String> guiLog = new java.util.LinkedList<String>();
Behaviour beh = new CyclicBehaviour(this) {
@Override
public void action() {
MessageTemplate mt = MessageTemplate.and(
MessageTemplate.MatchLanguage(codec.getName()),
MessageTemplate.MatchOntology(ontology.getName()));
ACLMessage msg = receive();
if (msg != null) {
try {
ContentElement ce = null;
if (msg.getPerformative() == ACLMessage.QUERY_IF) {
// Let JADE convert from String to Java objects
AID sender = msg.getSender();
ce = getContentManager().extractContent(msg);
// Worplace requests a reosurce
if (ce instanceof RequestResource) {
RequestResource p = (RequestResource) ce;
log("StorageAgent got an request for: "
+ p.getResource() + " " + p.getCount());
queueRequest(p, sender);
if (!inStorage(p)) {
requestProduction(p);
} else {
// process this request
processQueue();
}
// The LogisticAgent delivers an item
// from a WorplaceAgent to the Storage
} else if (ce instanceof Delivered) {
Delivered deliver = (Delivered) ce;
log("Storage received "
+ deliver.getResource() + "/"
+ deliver.getCount());
addToStorage(deliver);
// new items in storage, so queued request
// could be fullfilled and sent to workplaces
processQueue();
// A Workplace Agent tells the StorageAgent,
// that a product is ready to be picked up.
} else if (ce instanceof SetCompleted) {
System.out.println("StorageAgent received setcompleted");
SetCompleted sc = (SetCompleted) ce;
pickUp(sc, sender);
} else {
System.out.println("StorageAgent received unexpected, "
+ ce.toString());
}
} else {
System.out.println("StorageAgent received non-INFORM");
}
} catch (CodecException ce) {
ce.printStackTrace();
} catch (OntologyException oe) {
oe.printStackTrace();
}
} else {
block();
}
}
};
private StorageAgentGUI gui;
private void pickUp(SetCompleted sc, AID workplace) throws CodecException, OntologyException {
Deliver deliver = new Deliver(sc.getResource(), workplace,
new AID("Storage", false),
1);
ACLMessage pickUpMsg = new ACLMessage(ACLMessage.QUERY_IF);
pickUpMsg.addReceiver(pickLogisticAID());
pickUpMsg.setLanguage(codec.getName());
pickUpMsg.setOntology(ontology.getName());
getContentManager().fillContent(pickUpMsg, deliver);
send(pickUpMsg);
}
private void requestProduction(RequestResource p) throws CodecException, OntologyException {
RequestProduction request = new RequestProduction(p.getResource(), 0);
// request the missing number of items from MonitorAgent
int gotN = 0;
int needN = p.getCount();
if (storage.containsKey(p.getResource())) {
gotN = storage.get(p.getResource());
}
request.setCount(needN - gotN);
ACLMessage requestMsg = new ACLMessage(ACLMessage.QUERY_IF);
requestMsg.addReceiver(new AID("Monitor@bifab", true));
requestMsg.setLanguage(codec.getName());
requestMsg.setOntology(ontology.getName());
getContentManager().fillContent(requestMsg, request);
send(requestMsg);
}
private void queueRequest(RequestResource p, AID sender) {
requestQueue.add(p);
requestSenders.put(p, sender);
}
private void processQueue() throws CodecException, OntologyException {
ArrayList<RequestResource> toDelete = new ArrayList<RequestResource>();
for (Iterator it = requestQueue.iterator(); it.hasNext();) {
RequestResource p = (RequestResource) it.next();
if (inStorage(p)) {
// deliver
Deliver deliver = new Deliver(p.getResource(),
new AID("Storage", false),
p.getRequester(),
p.getCount());
AID logisticAgent = pickLogisticAID();
log("Storage assigns delivery " + p.getResource()
+ " to " + logisticAgent.getLocalName() + " for delivery to "
+ p.getRequester().getLocalName());
ACLMessage deliverMsg = new ACLMessage(ACLMessage.QUERY_IF);
deliverMsg.addReceiver(logisticAgent);
deliverMsg.setLanguage(codec.getName());
deliverMsg.setOntology(ontology.getName());
getContentManager().fillContent(deliverMsg, deliver);
send(deliverMsg);
// remove
takeFromStorage(p);
requestSenders.remove(p);
toDelete.add(p);
}
}
for (RequestResource p : toDelete) {
requestQueue.remove(p);
}
}
private AID pickLogisticAID() {
try {
DFAgentDescription tmpl = new DFAgentDescription();
ServiceDescription sd = new ServiceDescription();
sd.setType("Logistics");
tmpl.addServices(sd);
DFAgentDescription[] result = DFService.search(this, tmpl);
Random r = new Random();
return result[r.nextInt(result.length)].getName();
} catch (FIPAException ex) {
Logger.getLogger(StorageAgent.class.getName()).log(Level.SEVERE, null, ex);
}
return null;
}
private boolean inStorage(RequestResource p) {
if (storage.containsKey(p.getResource())) {
int needN = p.getCount();
int gotN = storage.get(p.getResource());
return (needN <= gotN);
} else {
return false;
}
}
private void takeFromStorage(RequestResource p) {
if (inStorage(p)) {
int needN = p.getCount();
storage.put(p.getResource(), storage.get(p.getResource()) - p.getCount());
}
}
private void addToStorage(Delivered d) {
int gotN = 0;
if (storage.containsKey(d.getResource())) {
gotN = storage.get(d.getResource());
}
storage.put(d.getResource(), gotN + d.getCount());
dumpStorage();
}
private void dumpStorage() {
Set<String> keys = storage.keySet();
System.out.println("StorageMananger: current storage");
for (Iterator it = keys.iterator(); it.hasNext();) {
String entry = (String) it.next();
System.out.println("\tStorageManager: " + entry + "\t\t" + storage.get(entry));
gui.setStorageCount(entry, storage.get(entry));
int req = 0;
for (Iterator itReq = requestQueue.iterator(); itReq.hasNext();) {
RequestResource p = (RequestResource) itReq.next();
if (p.getResource().equals(entry)) {
req += p.getCount();
}
}
gui.setRequestedCount(entry, req);
}
}
private void log(String msg) {
System.out.println(msg);
gui.addLog(msg);
}
@Override
protected void setup() {
getContentManager().registerLanguage(codec);
getContentManager().registerOntology(ontology);
gui = new StorageAgentGUI();
gui.setVisible(true);
storage = new HashMap<String, Integer>();
requestSenders = new HashMap<RequestResource, AID>();
requestQueue = new ArrayList<RequestResource>();
addBehaviour(beh);
}
@Override
protected void takeDown() {
System.out.println("StorageAgent " + getAID().getName() + "exits.");
}
}