package protocol; import java.util.List; import java.util.ArrayList; import java.util.concurrent.BlockingQueue; import onetomany.bargainingchipsgame.interactions.Offer; import onetomany.bargainingchipsgame.interactions.OfferBy; /** * A (possibly asynchronous) protocol between two agents An and B. * The protocol acts as the postman of delivering messages between the agents and validates their messages. * The protocol keeps the one official (synchronized) log of what has happened. */ public abstract class BilateralProtocol implements Runnable { // Messaging to and from A and B protected BlockingQueue fromA; protected BlockingQueue toA; protected BlockingQueue fromB; protected BlockingQueue toB; protected List log; public BilateralProtocol(BlockingQueue fromA, BlockingQueue toA, BlockingQueue fromB, BlockingQueue toB) { super(); this.fromA = fromA; this.toA = toA; this.fromB = fromB; this.toB = toB; this.log = new ArrayList(); } protected abstract boolean validate(OfferBy o); @Override public void run() { String sender = "A"; // Wait for a message from A or B try { while (true) { BlockingQueue from = from(sender); // starts with A BlockingQueue to = to(sender); // starts with B Offer o = from.poll(); if (o != null) { OfferBy ob = new OfferBy(sender, o); if (validate(ob)) { log(ob); to.put(o); } else // drop! System.err.println("Warning: " + ob + " was not a valid offer. Log: " + log.toString()); } // Swap the queue to check: A <-> B sender = swapRole(sender, "A", "B"); } } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } private String swapRole(String x, String y, String z) { return x.equals(y) ? z : y; } private BlockingQueue from(String sender) { return "A".equals(sender) ? fromA : fromB; } private BlockingQueue to(String sender) { return "A".equals(sender) ? toB : toA; } private void log(OfferBy ob) { log.add(ob); System.out.println("Logged: " + ob); } protected OfferBy getLastOffer() { return log.get(log.size() - 1); } }