Reformatted code

This commit is contained in:
2023-01-14 16:34:06 +01:00
parent 7bbcfaed36
commit 6659f96257
5 changed files with 306 additions and 246 deletions

5
.gitignore vendored Normal file
View File

@@ -0,0 +1,5 @@
*
!build.xml
!jade
!src
!.gitignore

View File

@@ -10,57 +10,59 @@ import jade.domain.FIPAException;
import jade.domain.FIPAAgentManagement.DFAgentDescription; import jade.domain.FIPAAgentManagement.DFAgentDescription;
import jade.domain.FIPAAgentManagement.ServiceDescription; import jade.domain.FIPAAgentManagement.ServiceDescription;
public class BookBuyerAgent extends Agent { public class BookBuyerAgent extends Agent
private BookBuyerGui myGui; {
private String targetBookTitle; private BookBuyerGui myGui;
private String targetBookTitle;
//list of found sellers
private AID[] sellerAgents; //list of found sellers
private AID[] sellerAgents;
protected void setup() {
targetBookTitle = ""; protected void setup()
System.out.println("Hello! " + getAID().getLocalName() + " is ready for the purchase order."); {
myGui = new BookBuyerGui(this); targetBookTitle = "";
myGui.display(); System.out.println("Hello! " + getAID().getLocalName() + " is ready for the purchase order.");
myGui = new BookBuyerGui(this);
myGui.display();
//time interval for buyer for sending subsequent CFP //time interval for buyer for sending subsequent CFP
//as a CLI argument //as a CLI argument
int interval = 20000; int interval = 20000;
Object[] args = getArguments(); Object[] args = getArguments();
if (args != null && args.length > 0) interval = Integer.parseInt(args[0].toString()); if (args != null && args.length > 0) interval = Integer.parseInt(args[0].toString());
addBehaviour(new TickerBehaviour(this, interval) addBehaviour(new TickerBehaviour(this, interval)
{ {
protected void onTick() protected void onTick()
{ {
//search only if the purchase task was ordered //search only if the purchase task was ordered
if (!targetBookTitle.equals("")) if (!targetBookTitle.equals(""))
{ {
System.out.println(getAID().getLocalName() + ": I'm looking for " + targetBookTitle); System.out.println(getAID().getLocalName() + ": I'm looking for " + targetBookTitle);
//update a list of known sellers (DF) //update a list of known sellers (DF)
DFAgentDescription template = new DFAgentDescription(); DFAgentDescription template = new DFAgentDescription();
ServiceDescription sd = new ServiceDescription(); ServiceDescription sd = new ServiceDescription();
sd.setType("book-selling"); sd.setType("book-selling");
template.addServices(sd); template.addServices(sd);
try try
{ {
DFAgentDescription[] result = DFService.search(myAgent, template); DFAgentDescription[] result = DFService.search(myAgent, template);
System.out.println(getAID().getLocalName() + ": the following sellers have been found"); System.out.println(getAID().getLocalName() + ": the following sellers have been found");
sellerAgents = new AID[result.length]; sellerAgents = new AID[result.length];
for (int i = 0; i < result.length; ++i) for (int i = 0; i < result.length; ++i)
{ {
sellerAgents[i] = result[i].getName(); sellerAgents[i] = result[i].getName();
System.out.println(sellerAgents[i].getLocalName()); System.out.println(sellerAgents[i].getLocalName());
} }
} }
catch (FIPAException fe) catch (FIPAException fe)
{ {
fe.printStackTrace(); fe.printStackTrace();
} }
myAgent.addBehaviour(new RequestPerformer()); myAgent.addBehaviour(new RequestPerformer());
} }
} }
}); });
} }
//invoked from GUI, when purchase was ordered //invoked from GUI, when purchase was ordered
public void lookForTitle(final String title) public void lookForTitle(final String title)
@@ -75,99 +77,111 @@ public class BookBuyerAgent extends Agent {
}); });
} }
protected void takeDown() { protected void takeDown()
{
myGui.dispose(); myGui.dispose();
System.out.println("Buyer agent " + getAID().getLocalName() + " terminated."); System.out.println("Buyer agent " + getAID().getLocalName() + " terminated.");
} }
private class RequestPerformer extends Behaviour { private class RequestPerformer extends Behaviour
private AID bestSeller; {
private int bestPrice; private AID bestSeller;
private int repliesCnt = 0; private int bestPrice;
private MessageTemplate mt; private int repliesCnt = 0;
private int step = 0; private MessageTemplate mt;
private int step = 0;
public void action() {
switch (step) { public void action()
case 0: {
//call for proposal (CFP) to found sellers switch (step)
ACLMessage cfp = new ACLMessage(ACLMessage.CFP); {
for (int i = 0; i < sellerAgents.length; ++i) { case 0:
cfp.addReceiver(sellerAgents[i]); //call for proposal (CFP) to found sellers
} ACLMessage cfp = new ACLMessage(ACLMessage.CFP);
cfp.setContent(targetBookTitle); for (int i = 0; i < sellerAgents.length; ++i)
cfp.setConversationId("book-trade"); {
cfp.setReplyWith("cfp"+System.currentTimeMillis()); //unique value cfp.addReceiver(sellerAgents[i]);
myAgent.send(cfp); }
mt = MessageTemplate.and(MessageTemplate.MatchConversationId("book-trade"), cfp.setContent(targetBookTitle);
MessageTemplate.MatchInReplyTo(cfp.getReplyWith())); cfp.setConversationId("book-trade");
step = 1; cfp.setReplyWith("cfp"+System.currentTimeMillis()); //unique value
break; myAgent.send(cfp);
case 1: mt = MessageTemplate.and(MessageTemplate.MatchConversationId("book-trade"),
//collect proposals MessageTemplate.MatchInReplyTo(cfp.getReplyWith()));
ACLMessage reply = myAgent.receive(mt); step = 1;
if (reply != null) { break;
if (reply.getPerformative() == ACLMessage.PROPOSE) { case 1:
//proposal received //collect proposals
int price = Integer.parseInt(reply.getContent()); ACLMessage reply = myAgent.receive(mt);
if (bestSeller == null || price < bestPrice) { if (reply != null)
//the best proposal as for now {
bestPrice = price; if (reply.getPerformative() == ACLMessage.PROPOSE)
bestSeller = reply.getSender(); {
} //proposal received
} int price = Integer.parseInt(reply.getContent());
repliesCnt++; if (bestSeller == null || price < bestPrice)
if (repliesCnt >= sellerAgents.length) { {
//all proposals have been received //the best proposal as for now
step = 2; bestPrice = price;
} bestSeller = reply.getSender();
} }
else { }
block(); repliesCnt++;
} if (repliesCnt >= sellerAgents.length)
break; {
case 2: //all proposals have been received
//best proposal consumption - purchase step = 2;
ACLMessage order = new ACLMessage(ACLMessage.ACCEPT_PROPOSAL); }
order.addReceiver(bestSeller); }
order.setContent(targetBookTitle); else
order.setConversationId("book-trade"); {
order.setReplyWith("order"+System.currentTimeMillis()); block();
myAgent.send(order); }
mt = MessageTemplate.and(MessageTemplate.MatchConversationId("book-trade"), break;
MessageTemplate.MatchInReplyTo(order.getReplyWith())); case 2:
step = 3; //best proposal consumption - purchase
break; ACLMessage order = new ACLMessage(ACLMessage.ACCEPT_PROPOSAL);
case 3: order.addReceiver(bestSeller);
//seller confirms the transaction order.setContent(targetBookTitle);
reply = myAgent.receive(mt); order.setConversationId("book-trade");
if (reply != null) { order.setReplyWith("order"+System.currentTimeMillis());
if (reply.getPerformative() == ACLMessage.INFORM) { myAgent.send(order);
//purchase succeeded mt = MessageTemplate.and(MessageTemplate.MatchConversationId("book-trade"),
System.out.println(getAID().getLocalName() + ": " + targetBookTitle + " purchased for " + bestPrice + " from " + reply.getSender().getLocalName()); MessageTemplate.MatchInReplyTo(order.getReplyWith()));
System.out.println(getAID().getLocalName() + ": waiting for the next purchase order."); step = 3;
targetBookTitle = ""; break;
//myAgent.doDelete(); case 3:
} //seller confirms the transaction
else { reply = myAgent.receive(mt);
System.out.println(getAID().getLocalName() + ": purchase has failed. " + targetBookTitle + " was sold in the meantime."); if (reply != null) {
} if (reply.getPerformative() == ACLMessage.INFORM) {
step = 4; //this state ends the purchase process //purchase succeeded
} System.out.println(getAID().getLocalName() + ": " + targetBookTitle + " purchased for " + bestPrice + " from " + reply.getSender().getLocalName());
else { System.out.println(getAID().getLocalName() + ": waiting for the next purchase order.");
block(); targetBookTitle = "";
} //myAgent.doDelete();
break; }
} else {
} System.out.println(getAID().getLocalName() + ": purchase has failed. " + targetBookTitle + " was sold in the meantime.");
}
public boolean done() { step = 4; //this state ends the purchase process
if (step == 2 && bestSeller == null) { }
System.out.println(getAID().getLocalName() + ": " + targetBookTitle + " is not on sale."); else {
} block();
//process terminates here if purchase has failed (title not on sale) or book was successfully bought }
return ((step == 2 && bestSeller == null) || step == 4); break;
} }
}
public boolean done()
{
if (step == 2 && bestSeller == null)
{
System.out.println(getAID().getLocalName() + ": " + targetBookTitle + " is not on sale.");
}
//process terminates here if purchase has failed (title not on sale) or book was successfully bought
return ((step == 2 && bestSeller == null) || step == 4);
}
} }
} }

View File

@@ -6,12 +6,14 @@ import java.awt.*;
import java.awt.event.*; import java.awt.event.*;
import javax.swing.*; import javax.swing.*;
class BookBuyerGui extends JFrame { class BookBuyerGui extends JFrame
{
private BookBuyerAgent myAgent; private BookBuyerAgent myAgent;
private JTextField titleField; private JTextField titleField;
BookBuyerGui(BookBuyerAgent a) { BookBuyerGui(BookBuyerAgent a)
{
super(a.getLocalName()); super(a.getLocalName());
myAgent = a; myAgent = a;
@@ -24,14 +26,18 @@ class BookBuyerGui extends JFrame {
getContentPane().add(p, BorderLayout.CENTER); getContentPane().add(p, BorderLayout.CENTER);
JButton addButton = new JButton("Search"); JButton addButton = new JButton("Search");
addButton.addActionListener( new ActionListener() { addButton.addActionListener( new ActionListener()
public void actionPerformed(ActionEvent ev) { {
try { public void actionPerformed(ActionEvent ev)
{
try
{
String title = titleField.getText().trim(); String title = titleField.getText().trim();
myAgent.lookForTitle(title); myAgent.lookForTitle(title);
titleField.setText(""); titleField.setText("");
} }
catch (Exception e) { catch (Exception e)
{
JOptionPane.showMessageDialog(BookBuyerGui.this, "Invalid values. " + e.getMessage(), "Error", JOptionPane.ERROR_MESSAGE); JOptionPane.showMessageDialog(BookBuyerGui.this, "Invalid values. " + e.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
} }
} }
@@ -40,16 +46,21 @@ class BookBuyerGui extends JFrame {
p.add(addButton); p.add(addButton);
getContentPane().add(p, BorderLayout.SOUTH); getContentPane().add(p, BorderLayout.SOUTH);
addWindowListener(new WindowAdapter() { addWindowListener(
public void windowClosing(WindowEvent e) { new WindowAdapter()
myAgent.doDelete(); {
public void windowClosing(WindowEvent e)
{
myAgent.doDelete();
}
} }
} ); );
setResizable(false); setResizable(false);
} }
public void display() { public void display()
{
pack(); pack();
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
int centerX = (int)screenSize.getWidth() / 2; int centerX = (int)screenSize.getWidth() / 2;

View File

@@ -11,108 +11,131 @@ import jade.domain.FIPAAgentManagement.ServiceDescription;
import java.util.*; import java.util.*;
public class BookSellerAgent extends Agent { public class BookSellerAgent extends Agent
private Hashtable catalogue; {
private BookSellerGui myGui; private Hashtable catalogue;
private BookSellerGui myGui;
protected void setup() { protected void setup()
catalogue = new Hashtable(); {
myGui = new BookSellerGui(this); catalogue = new Hashtable();
myGui.display(); myGui = new BookSellerGui(this);
myGui.display();
//book selling service registration at DF //book selling service registration at DF
DFAgentDescription dfd = new DFAgentDescription(); DFAgentDescription dfd = new DFAgentDescription();
dfd.setName(getAID()); dfd.setName(getAID());
ServiceDescription sd = new ServiceDescription(); ServiceDescription sd = new ServiceDescription();
sd.setType("book-selling"); sd.setType("book-selling");
sd.setName("JADE-book-trading"); sd.setName("JADE-book-trading");
dfd.addServices(sd); dfd.addServices(sd);
try { try
DFService.register(this, dfd); {
} DFService.register(this, dfd);
catch (FIPAException fe) { }
fe.printStackTrace(); catch (FIPAException fe)
} {
fe.printStackTrace();
addBehaviour(new OfferRequestsServer()); }
addBehaviour(new PurchaseOrdersServer()); addBehaviour(new OfferRequestsServer());
}
protected void takeDown() { addBehaviour(new PurchaseOrdersServer());
//book selling service deregistration at DF }
try {
DFService.deregister(this);
}
catch (FIPAException fe) {
fe.printStackTrace();
}
myGui.dispose();
System.out.println("Seller agent " + getAID().getName() + " terminated.");
}
//invoked from GUI, when a new book is added to the catalogue protected void takeDown()
public void updateCatalogue(final String title, final int price) { {
addBehaviour(new OneShotBehaviour() { //book selling service deregistration at DF
public void action() { try
catalogue.put(title, new Integer(price)); {
System.out.println(getAID().getLocalName() + ": " + title + " put into the catalogue. Price = " + price); DFService.deregister(this);
} }
} ); catch (FIPAException fe)
} {
fe.printStackTrace();
}
myGui.dispose();
System.out.println("Seller agent " + getAID().getName() + " terminated.");
}
//invoked from GUI, when a new book is added to the catalogue
public void updateCatalogue(final String title, final int price)
{
addBehaviour(new OneShotBehaviour()
{
public void action()
{
catalogue.put(title, new Integer(price));
System.out.println(getAID().getLocalName() + ": " + title + " put into the catalogue. Price = " + price);
}
} );
}
private class OfferRequestsServer extends CyclicBehaviour { private class OfferRequestsServer extends CyclicBehaviour
public void action() { {
//proposals only template public void action()
MessageTemplate mt = MessageTemplate.MatchPerformative(ACLMessage.CFP); {
ACLMessage msg = myAgent.receive(mt); //proposals only template
if (msg != null) { MessageTemplate mt = MessageTemplate.MatchPerformative(ACLMessage.CFP);
String title = msg.getContent(); ACLMessage msg = myAgent.receive(mt);
ACLMessage reply = msg.createReply(); if (msg != null)
Integer price = (Integer) catalogue.get(title); {
if (price != null) { String title = msg.getContent();
//title found in the catalogue, respond with its price as a proposal ACLMessage reply = msg.createReply();
reply.setPerformative(ACLMessage.PROPOSE); Integer price = (Integer) catalogue.get(title);
reply.setContent(String.valueOf(price.intValue())); if (price != null)
} {
else { //title found in the catalogue, respond with its price as a proposal
//title not found in the catalogue reply.setPerformative(ACLMessage.PROPOSE);
reply.setPerformative(ACLMessage.REFUSE); reply.setContent(String.valueOf(price.intValue()));
reply.setContent("not-available"); }
} else
myAgent.send(reply); {
} //title not found in the catalogue
else { reply.setPerformative(ACLMessage.REFUSE);
block(); reply.setContent("not-available");
} }
} myAgent.send(reply);
}
else
{
block();
}
}
} }
private class PurchaseOrdersServer extends CyclicBehaviour { private class PurchaseOrdersServer extends CyclicBehaviour
public void action() { {
//purchase order as proposal acceptance only template public void action()
MessageTemplate mt = MessageTemplate.MatchPerformative(ACLMessage.ACCEPT_PROPOSAL); {
ACLMessage msg = myAgent.receive(mt); //purchase order as proposal acceptance only template
if (msg != null) { MessageTemplate mt = MessageTemplate.MatchPerformative(ACLMessage.ACCEPT_PROPOSAL);
String title = msg.getContent(); ACLMessage msg = myAgent.receive(mt);
ACLMessage reply = msg.createReply(); if (msg != null)
Integer price = (Integer) catalogue.remove(title); {
if (price != null) { String title = msg.getContent();
reply.setPerformative(ACLMessage.INFORM); ACLMessage reply = msg.createReply();
System.out.println(getAID().getLocalName() + ": " + title + " sold to " + msg.getSender().getLocalName()); Integer price = (Integer) catalogue.remove(title);
} if (price != null)
else { {
//title not found in the catalogue, sold to another agent in the meantime (after proposal submission) reply.setPerformative(ACLMessage.INFORM);
reply.setPerformative(ACLMessage.FAILURE); System.out.println(getAID().getLocalName() + ": " + title + " sold to " + msg.getSender().getLocalName());
reply.setContent("not-available"); }
} else
myAgent.send(reply); {
} //title not found in the catalogue, sold to another agent in the meantime (after proposal submission)
else { reply.setPerformative(ACLMessage.FAILURE);
block(); reply.setContent("not-available");
}
myAgent.send(reply);
}
else
{
block();
}
} }
}
} }
} }

View File

@@ -6,12 +6,14 @@ import java.awt.*;
import java.awt.event.*; import java.awt.event.*;
import javax.swing.*; import javax.swing.*;
class BookSellerGui extends JFrame { class BookSellerGui extends JFrame
{
private BookSellerAgent myAgent; private BookSellerAgent myAgent;
private JTextField titleField, priceField; private JTextField titleField, priceField;
BookSellerGui(BookSellerAgent a) { BookSellerGui(BookSellerAgent a)
{
super(a.getLocalName()); super(a.getLocalName());
myAgent = a; myAgent = a;
@@ -27,9 +29,11 @@ class BookSellerGui extends JFrame {
getContentPane().add(p, BorderLayout.CENTER); getContentPane().add(p, BorderLayout.CENTER);
JButton addButton = new JButton("Add"); JButton addButton = new JButton("Add");
addButton.addActionListener( new ActionListener() { addButton.addActionListener( new ActionListener()
{
public void actionPerformed(ActionEvent ev) { public void actionPerformed(ActionEvent ev) {
try { try
{
String title = titleField.getText().trim(); String title = titleField.getText().trim();
String price = priceField.getText().trim(); String price = priceField.getText().trim();
myAgent.updateCatalogue(title, Integer.parseInt(price)); myAgent.updateCatalogue(title, Integer.parseInt(price));
@@ -45,8 +49,10 @@ class BookSellerGui extends JFrame {
p.add(addButton); p.add(addButton);
getContentPane().add(p, BorderLayout.SOUTH); getContentPane().add(p, BorderLayout.SOUTH);
addWindowListener(new WindowAdapter() { addWindowListener(new WindowAdapter()
public void windowClosing(WindowEvent e) { {
public void windowClosing(WindowEvent e)
{
myAgent.doDelete(); myAgent.doDelete();
} }
} ); } );
@@ -54,12 +60,13 @@ class BookSellerGui extends JFrame {
setResizable(false); setResizable(false);
} }
public void display() { public void display()
{
pack(); pack();
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
int centerX = (int)screenSize.getWidth() / 2; int centerX = (int)screenSize.getWidth() / 2;
int centerY = (int)screenSize.getHeight() / 2; int centerY = (int)screenSize.getHeight() / 2;
setLocation(centerX - getWidth() / 2, centerY - getHeight() / 2); setLocation(centerX - getWidth() / 2, centerY - getHeight() / 2);
setVisible(true); setVisible(true);
} }
} }