package org.ntlab.deltaViewer;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
import org.ntlab.deltaExtractor.Alias;
import org.ntlab.deltaExtractor.IAliasCollector;
/**
* CollaborationAliasCollector is IAliasCollector implementation class to merge aliasList in time stamp order.
*
* @author Nitta Lab.
*/
public class CollaborationAliasCollector implements IAliasCollector {
// Execution order.
private List<Alias> aliasList = new ArrayList<>();
public CollaborationAliasCollector(IAliasCollector dac) {
aliasList.addAll(dac.getAliasList());
aliasList = sortAliasListByTimeStamp(aliasList);
}
/*
* Don't write anything here.
*/
@Override
public void addAlias(Alias alias) {
}
@Override
public List<Alias> getAliasList() {
return aliasList;
}
/**
* Merge other into aliasList(this) in time stamp order.
* @param other IAliasCollector to be merged into the aliasList.
*/
public void merge(IAliasCollector other) {
List<Alias> otherAliasList = other.getAliasList();
otherAliasList = sortAliasListByTimeStamp(otherAliasList);
int otherIdx = 0; // Index of otherAliasList
int thisIdx = 0; // Index of thisAliasList
while(otherIdx < otherAliasList.size()) {
Alias otherAlias = otherAliasList.get(otherIdx);
if (thisIdx >= aliasList.size()) {
aliasList.add(otherAlias);
otherIdx++; thisIdx++;
continue;
}
Alias thisAlias = aliasList.get(thisIdx);
if (otherAlias.equals(thisAlias)) {
otherIdx++; thisIdx++;
} else {
long otherAliasTs = otherAlias.getTimeStamp();
long thisAliasTs = thisAlias.getTimeStamp();
if (otherAliasTs < thisAliasTs) {
aliasList.add(thisIdx, otherAlias);
otherIdx++; thisIdx++;
} else if (otherAliasTs > thisAliasTs) {
thisIdx++;
} else {
if (aliasList.contains(otherAlias)) {
otherIdx++;
} else {
// BUGがあるかもしれません(ACTUAL_ARGUMENTとRECEIVERの出現順)
aliasList.add(thisIdx, otherAlias);
otherIdx++; thisIdx++;
}
}
}
}
}
/**
* Sort aliasList in time stamp order.
* @param aliasList AliasList to sort.
* @return Sorted AliasList.
*/
private List<Alias> sortAliasListByTimeStamp(List<Alias> aliasList) {
List<Alias> cloneAliasList = new ArrayList<>(aliasList);
List<Alias> sortedAliasList = cloneAliasList.stream().sorted(new Comparator<Alias>() {
@Override
public int compare(Alias alias1, Alias alias2) {
if (alias1.getTimeStamp() > alias2.getTimeStamp()) return 1;
else if (alias1.getTimeStamp() < alias2.getTimeStamp()) return -1;
return 0;
}
}
).collect(Collectors.toList());
return sortedAliasList;
}
}