law(L,authority(cA),language(java)) authority(cA,keyHash(3AC329C58B1234F5CFDF7DC0F0DE7472)) public class L extends Law{ public static final String secretary = "secretary@rutgers.edu"; public void adopted(String arg, String[] issuer, String[] subject, String[] attributes) { if (issuer.length != 0) { int index = attributes[0].indexOf(","); if (issuer[0].equals("cA") && subject[0].equals(Self) && attributes[0].equals("role(secretary)")) { doAdd("role(secretary)"); } else { if (issuer[0].equals("cA") && subject[0].equals(Self) && (index != -1) && (attributes[0].substring(attributes[0].indexOf(',')+1,attributes[0].length()-1).equals("role(leader)"))) { doAdd(attributes[0].substring(1,attributes[0].indexOf(','))); doAdd(attributes[0].substring(attributes[0].indexOf(',')+1,attributes[0].length()-1)); String content = getContentFromMessage(attributes[0].substring(1,attributes[0].indexOf(','))); doForward(Self, "register(" + content + ")", secretary); } if (issuer[0].equals("cA") && subject[0].equals(Self) && (index == -1)) { doAdd(attributes[0]); String content = getContentFromMessage(attributes[0]); doForward(Self, "register("+ content + ")", secretary); } } } else { doQuit(); } } public void sent(String source, String message, String dest) { if (message.startsWith("getTwins") && (dest.equals(secretary))) { doForward(); return; } if (message.equals("getCS")) { doDiscloseAllCS(); return; } if (message.equals("transfer(leader)")) { if ((CS.has("role(leader)")) && (CS.has("twins(" + dest + ",%Y,%Z)")) && (CS.has("name(%B)"))) { doRemove("role(leader)"); String destTerm = (CS.findT("twins(" + dest + ",%Y,%Z)")).toString(); int index1 = destTerm.indexOf(","); int index2 = destTerm.indexOf(",",index1+1); String addr1 = destTerm.substring(index1+1,index2); String addr2 = destTerm.substring(index2+1,destTerm.length()-1); String nameTerm = (CS.findT("name(%B)")).toString(); String name = getContentFromMessage(nameTerm); doForward(Self,"transfer(" + name + ",leader)",addr1); doForward(Self,"transfer(" + name + ",leader)",addr2); } return; } if (message.startsWith("command")) { if ((CS.has("role(leader)")) && (CS.has("twins(" + dest + ",%Y,%Z)")) && (CS.has("name(%B)"))) { String command = getContentFromMessage(message); String destTerm = (CS.findT("twins(" + dest + ",%Y,%Z)")).toString(); int index1 = destTerm.indexOf(","); int index2 = destTerm.indexOf(",",index1+1); String addr1 = destTerm.substring(index1+1,index2); String addr2 = destTerm.substring(index2+1,destTerm.length()-1); String nameTerm = (CS.findT("name(%B)")).toString(); String name = getContentFromMessage(nameTerm); doForward(Self,"command(" + name + "," + command + ")",addr1); doForward(Self,"command(" + name + "," + command + ")",addr2); } return; } } public void arrived(String source, String message, String dest) { String content = getContentFromMessage(message); if (message.startsWith("register") && (dest.equals(secretary))) { if (CS.has("participant(" + content + ",%A)")) { String participantTerm = (CS.findT("participant(" + content + ",%A)")).toString(); int index2 = participantTerm.indexOf(","); String addr1 = participantTerm.substring(index2+1,participantTerm.length()-1); if (!addr1.equals(source)) { doRemove("participant(" + content + "," + addr1 + ")"); doAdd("member(" + content + "," + addr1 + "," + source + ")"); } else { doRemove("participant(" + content + "," + addr1 + ")"); } } else { if (! CS.has("member(" + content + ",%A,%B)")) { doAdd("participant(" + content + "," + source + ")"); } } doDeliver(); return; } if (message.startsWith("getTwins") && (dest.equals(secretary))) { if (CS.has("member(" + content + ",%A,%B)")) { String memberTerm = (CS.findT("member(" + content + ",%A,%B)")).toString(); int index3 = memberTerm.indexOf(","); int index4 = memberTerm.indexOf(",",index3+1); String addr1 = memberTerm.substring(index3+1,index4); String addr2 = memberTerm.substring(index4+1,memberTerm.length()-1); if ((!addr1.equals(source)) && (!addr2.equals(source))) { if (CS.has("member(%W," + source + ",%Y)")) { String destTerm = (CS.findT("member(%W," + source + ",%Y)")).toString(); int index5 = destTerm.indexOf(","); int index6 = destTerm.indexOf(",",index5+1); String dest2 = destTerm.substring(index6+1,destTerm.length()-1); doForward(Self,"twinsInfo(" + content + "," + addr1 + "," + addr2 + ")",source); doForward(Self,"twinsInfo(" + content + "," + addr1 + "," + addr2 + ")",dest2); } if (CS.has("member(%W," + "%Y," + source + ")")) { String destTerm = (CS.findT("member(%W," + "%Y," + source + ")")).toString(); int index5 = destTerm.indexOf(","); int index6 = destTerm.indexOf(",",index5+1); String dest2 = destTerm.substring(index5+1,index6); doForward(Self,"twinsInfo(" + content + "," + addr1 + "," + addr2 + ")",source); doForward(Self,"twinsInfo(" + content + "," + addr1 + "," + addr2 + ")",dest2); } } } doDeliver(); return; } if (message.startsWith("twinsInfo") && (source.equals(secretary))) { doDeliver(); if (! CS.has("twins(" + content + ")")) { doAdd("twins(" + content + ")"); } int index1 = content.indexOf(","); int index2 = content.indexOf(",",index1+1); String name = content.substring(0,index1); String addr1 = content.substring(index1+1,index2); String addr2 = content.substring(index2+1,content.length()); if (CS.has("pendingTwinsIdentification(transfer(" + content + ",leader))")) { doRemove("pendingTwinsIdentification(transfer(" + content + ",leader))"); doAdd("role(leader)"); doDeliver(Self,"newLeader",Self); } if (CS.has("pendingTwinsIdentification(transfer(" + name + "," + addr2 + "," + addr1 + ",leader))")) { doRemove("pendingTwinsIdentification(transfer(" + name + "," + addr2 + "," + addr1 + ",leader))"); doAdd("role(leader)"); doDeliver(Self,"newLeader",Self); } if (CS.has("pendingTwinsIdentification(command(" + content + ",%C))")) { String pendingTwinsIdentificationTerm = (CS.findT("pendingTwinsIdentification(command(" + content + ",%C))")).toString(); int index3 = pendingTwinsIdentificationTerm.indexOf(","); int index4 = pendingTwinsIdentificationTerm.indexOf(",",index3+1); int index5 = pendingTwinsIdentificationTerm.indexOf(",",index4+1); String command = pendingTwinsIdentificationTerm.substring(index5+1,pendingTwinsIdentificationTerm.length()-2); doRemove("pendingTwinsIdentification(command(" + content + "," + command + "))"); doDeliver(Self,"confirmedCommand(" + name + "," + command + ")",Self); } if (CS.has("pendingTwinsIdentification(command(" + name + "," + addr2 + "," + addr1 + ",%C))")) { String pendingTwinsIdentificationTerm = (CS.findT("pendingTwinsIdentification(command(" + name + "," + addr2 + "," + addr1 + ",%C))")).toString(); int index3 = pendingTwinsIdentificationTerm.indexOf(","); int index4 = pendingTwinsIdentificationTerm.indexOf(",",index3+1); int index5 = pendingTwinsIdentificationTerm.indexOf(",",index4+1); String command = pendingTwinsIdentificationTerm.substring(index5+1,pendingTwinsIdentificationTerm.length()-2); doRemove("pendingTwinsIdentification(command(" + name + "," + addr2 + "," + addr1 + "," + command + "))"); doDeliver(Self,"confirmedCommand(" + name + "," + command + ")",Self); } return; } if (message.startsWith("transfer")) { doDeliver(); int index1 = content.indexOf(","); String sender = content.substring(0,index1); if (CS.has("pending(transfer(" + sender + ",%M," + "leader))")) { String pendingTerm = (CS.findT("pending(transfer(" + sender + ",%M," + "leader))")).toString(); int index2 = pendingTerm.indexOf(","); int index3 = pendingTerm.indexOf(",",index2+1); String confirmationAddr = pendingTerm.substring(index2+1,index3); if ((CS.has("twins(" + sender + "," + source + "," + confirmationAddr + ")")) || (CS.has("twins(" + sender + "," + confirmationAddr + "," + source + ")"))) { doRemove("pending(transfer(" + sender + "," + confirmationAddr + ",leader))"); doAdd("role(leader)"); doDeliver(Self,"newLeader",Self); } else { doRemove("pending(transfer(" + sender + "," + confirmationAddr + ",leader))"); doAdd("pendingTwinsIdentification(transfer(" + sender + "," + confirmationAddr + "," + source + ",leader))"); } } else { doAdd("pending(transfer(" + sender + "," + source + ",leader))"); /* Don't comment the following "if code" (3 lines) only when testing the (transfer(x1) -> twinsInfo -> transfer(x2)) or (transfer(x2) -> twinsInfo -> transfer(x1)) message sequences */ if (! CS.has("twins(" + sender + ",%C,%D)")) { doForward(Self,"getTwins(" +sender + ")",secretary); } } return; } if (message.startsWith("command")) { doDeliver(); int index1 = content.indexOf(","); String sender = content.substring(0,index1); String command = content.substring(index1+1,content.length()); if (CS.has("pending(command(" + sender + ",%M," + command + "))")) { String pendingTerm = (CS.findT("pending(command(" + sender + ",%M," + command + "))")).toString(); int index2 = pendingTerm.indexOf(","); int index3 = pendingTerm.indexOf(",",index2+1); String confirmationAddr = pendingTerm.substring(index2+1,index3); if ((CS.has("twins(" + sender + "," + source + "," + confirmationAddr + ")")) || (CS.has("twins(" + sender + "," + confirmationAddr + "," + source + ")"))) { doRemove("pending(command(" + sender + "," + confirmationAddr + "," + command + "))"); doDeliver(Self,"confirmed" + message,Self); } else { doRemove("pending(command(" + sender + "," + confirmationAddr + "," + command + "))"); doAdd("pendingTwinsIdentification(command(" + sender + "," + confirmationAddr + "," + source + "," + command + "))"); } } else { doAdd("pending(command(" + sender + "," + source + "," + command + "))"); /* Don't comment the following "if code" (3 lines) only when testing the (command(x1) -> twinsInfo -> command(x2)) or (command(x2) -> twinsInfo -> command(x1)) message sequences */ if (! CS.has("twins(" + sender + ",%C,%D)")) { doForward(Self,"getTwins(" +sender + ")",secretary); } } return; } } public void disconnected() { doQuit(); } /** Helper method to parse the argument out of a regular expression */ public String getContentFromMessage(String anyMessage) { int index = anyMessage.indexOf("("); if (index == -1) return ""; else return anyMessage.substring(index+1, anyMessage.length()-1); } }