* @throws InterruptedException
*/
public void writeDataFolder(@NonNull File rootFolder)
throws IOException, DuplicateDataException, ExecutionException, InterruptedException {
WaitableExecutor executor = new WaitableExecutor();
// get all the items keys.
Set<String> dataItemKeys = Sets.newHashSet();
for (S dataSet : mDataSets) {
// quick check on duplicates in the resource set.
dataSet.checkItems();
ListMultimap<String, I> map = dataSet.getDataMap();
dataItemKeys.addAll(map.keySet());
}
// loop on all the data items.
for (String dataItemKey : dataItemKeys) {
// for each items, look in the data sets, starting from the end of the list.
I previouslyWritten = null;
I toWrite = null;
/*
* We are looking for what to write/delete: the last non deleted item, and the
* previously written one.
*/
setLoop: for (int i = mDataSets.size() - 1 ; i >= 0 ; i--) {
S dataSet = mDataSets.get(i);
// look for the resource key in the set
ListMultimap<String, I> itemMap = dataSet.getDataMap();
List<I> items = itemMap.get(dataItemKey);
if (items.isEmpty()) {
continue;
}
// The list can contain at max 2 items. One touched and one deleted.
// More than one deleted means there was more than one which isn't possible
// More than one touched means there is more than one and this isn't possible.
for (int ii = items.size() - 1 ; ii >= 0 ; ii--) {
I item = items.get(ii);
if (item.isWritten()) {
assert previouslyWritten == null;
previouslyWritten = item;
}
if (toWrite == null && !item.isRemoved()) {
toWrite = item;
}
if (toWrite != null && previouslyWritten != null) {
break setLoop;
}
}
}
// done searching, we should at least have something.
assert previouslyWritten != null || toWrite != null;
// now need to handle, the type of each (single res file, multi res file), whether
// they are the same object or not, whether the previously written object was deleted.
if (toWrite == null) {
// nothing to write? delete only then.
assert previouslyWritten.isRemoved();
removeItem(rootFolder, previouslyWritten, null /*replacedBy*/);
} else if (previouslyWritten == null || previouslyWritten == toWrite) {
// easy one: new or updated res
writeItem(rootFolder, toWrite, executor);
} else {
// replacement of a resource by another.
// first force the writing of the new one.
toWrite.setTouched();
// write the new value
writeItem(rootFolder, toWrite, executor);
removeItem(rootFolder, previouslyWritten, toWrite);
}
}
postWriteDataFolder(rootFolder);
executor.waitForTasks();
}