/**
* This software is GPLv2.
* Take a look at the LICENSE file for more info.
*/
package de.tu.dresden.dud.dc.InfoService;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Iterator;
import org.apache.log4j.Logger;
import de.tu.dresden.dud.dc.Connection;
import de.tu.dresden.dud.dc.Participant;
import de.tu.dresden.dud.dc.Util;
/**
* @author klobs
*
*/
public class InfoServiceInfoEarlyQuitServiceNotification extends InfoServiceInfo {
// Logging
private static Logger log = Logger.getLogger(InfoServiceInfoEarlyQuitServiceNotification.class);
private LinkedList<Participant> earlyLeavingParticipant = new LinkedList<Participant>();
private long workCycle = Long.MIN_VALUE;
private int roundNumber = Short.MIN_VALUE;
public InfoServiceInfoEarlyQuitServiceNotification(LinkedList<Participant> apl, long workCycleNumber, int roundNumber) {
ArrayList<byte[]> b = new ArrayList<byte[]>();
Iterator<Participant> ip = apl.iterator();
Participant p = null;
earlyLeavingParticipant = apl;
this.workCycle = workCycleNumber;
this.roundNumber = roundNumber;
byte[] wcn = Util.stuffLongIntoLong(workCycleNumber);
byte[] rn = Util.stuffIntIntoShort(roundNumber);
byte[] ac = Util.stuffIntIntoShort(apl.size());
b.add(Util
.stuffIntIntoShort(InfoServiceInfo.INFO_EARLYQUITNOTIFICATION));
b.add(wcn);
b.add(rn);
b.add(ac);
while (ip.hasNext()) {
p = ip.next();
b.add(Util.stuffIntIntoShort(p.getId().length()));
b.add(p.getId().getBytes());
b.add(Util.stuffIntIntoShort(p.getUsername().length()));
b.add(p.getUsername().getBytes());
b.add(Util.stuffIntIntoShort(p.getDSAPublicSignature().length));
b.add(p.getDSAPublicSignature());
b.add(Util.stuffIntIntoShort(p.getDHPublicPart().length));
b.add(p.getDHPublicPart());
b.add(Util.stuffIntIntoShort(p.getDHPublicPartSignature().length));
b.add(p.getDHPublicPartSignature());
}
for(int i = 0; i < b.size(); i++) {
info = Util.concatenate(info, b.get(i));
}
}
public InfoServiceInfoEarlyQuitServiceNotification(byte [] infopayload) {
info = infopayload;
int pc = 0;
int ul = 14;
ArrayList<byte[]> p = new ArrayList<byte[]>(5);
if (infopayload.length < 12) {
log.warn("Payload does not correspond to the required min size");
}
workCycle = Util.stuffBytesIntoLong(Util.getBytesByOffset(infopayload, 2, 8));
roundNumber = Util.stuffBytesIntoUInt(Util.getBytesByOffset(infopayload, 10, 2));
pc = Util.stuffBytesIntoUInt(Util.getBytesByOffset(infopayload, 12, 2));
for (int i = 0; i < pc; i++) {
for (int j = 0; j < 5; j++) {
if (infopayload.length >= ul + 2) {
int pl = Util.stuffBytesIntoUInt(Util.getBytesByOffset(infopayload, ul, 2));
ul = ul + 2;
if (infopayload.length >= ul + pl) {
p.add(j,Util.getBytesByOffset(infopayload, ul, pl));
ul = ul + pl;
} else {
log.warn("Payload has strange differences between indicated and effective length: wrong information about id lengths");
}
} else {
log.warn("Payload has strange differences between indicated and effective length: not enough data for the indicated number of users");
}
}
earlyLeavingParticipant.add(new Participant(new String(p.get(0)),
new String(p.get(1)), p.get(2), p.get(3), p.get(4)));
p.clear();
}
}
public static InfoServiceInfoEarlyQuitServiceNotification infoServiceInfoEarlyQuitServiceNotificationFor(Participant p, long workCycleNumber, int roundNumber){
LinkedList<Participant> a = new LinkedList<Participant>();
a.add(p);
return new InfoServiceInfoEarlyQuitServiceNotification(a, workCycleNumber, roundNumber);
}
public LinkedList<Participant> getEarlyLeavingParticipantIDs(){
return earlyLeavingParticipant;
}
public long getMissingInRoundNumber(){
return roundNumber;
}
public long getMissingInWorkCycle(){
return workCycle;
}
public void handleInfo(Connection c){
requestingconnection = c;
for(Participant p : earlyLeavingParticipant){
c.getAssociatedParticipantManager().removeParticipant(p);
}
}
}