| | |
| | | import org.opends.server.types.Modification; |
| | | |
| | | /** |
| | | * This class is used to store historical information for single valued |
| | | * attributes. |
| | | * One object of this type is created for each attribute that was changed in |
| | | * the entry. |
| | | * This class is used to store historical information for single valued attributes. |
| | | * One object of this type is created for each attribute that was changed in the entry. |
| | | * It allows to record the last time a given value was added, |
| | | * and the last time the whole attribute was deleted. |
| | | */ |
| | |
| | | switch (mod.getModificationType().asEnum()) |
| | | { |
| | | case DELETE: |
| | | this.addTime = null; |
| | | this.deleteTime = csn; |
| | | this.value = newValue; |
| | | lastMod = DEL; |
| | | delete(csn, newValue); |
| | | break; |
| | | |
| | | case ADD: |
| | | this.addTime = csn; |
| | | this.value = newValue; |
| | | lastMod = ADD; |
| | | add(csn, newValue); |
| | | break; |
| | | |
| | | case REPLACE: |
| | | if (newValue == null) |
| | | { |
| | | // REPLACE with null value is actually a DELETE |
| | | this.addTime = null; |
| | | this.deleteTime = csn; |
| | | this.value = null; |
| | | lastMod = DEL; |
| | | } |
| | | else |
| | | { |
| | | this.addTime = csn; |
| | | this.deleteTime = csn; |
| | | this.value = newValue; |
| | | lastMod = REPL; |
| | | } |
| | | replaceOrDelete(csn, newValue); |
| | | break; |
| | | |
| | | case INCREMENT: |
| | |
| | | } |
| | | } |
| | | |
| | | private void replaceOrDelete(CSN csn, ByteString newValue) |
| | | { |
| | | if (newValue != null) |
| | | { |
| | | replace(csn, newValue); |
| | | } |
| | | else |
| | | { |
| | | delete(csn, null); |
| | | } |
| | | } |
| | | |
| | | private void add(CSN csn, ByteString newValue) |
| | | { |
| | | addTime = csn; |
| | | value = newValue; |
| | | lastMod = ADD; |
| | | } |
| | | |
| | | private void replace(CSN csn, ByteString newValue) |
| | | { |
| | | addTime = csn; |
| | | deleteTime = csn; |
| | | value = newValue; |
| | | lastMod = REPL; |
| | | } |
| | | |
| | | private void delete(CSN csn, ByteString newValue) |
| | | { |
| | | addTime = null; |
| | | deleteTime = csn; |
| | | value = newValue; |
| | | lastMod = DEL; |
| | | } |
| | | |
| | | private void deleteWithoutDeleteTime() |
| | | { |
| | | addTime = null; |
| | | value = null; |
| | | lastMod = DEL; |
| | | } |
| | | |
| | | @Override |
| | | public boolean replayOperation(Iterator<Modification> modsIterator, CSN csn, |
| | | Entry modifiedEntry, Modification mod) |
| | |
| | | } |
| | | else |
| | | { |
| | | addTime = null; |
| | | lastMod = DEL; |
| | | value = null; |
| | | deleteWithoutDeleteTime(); |
| | | } |
| | | } |
| | | else |
| | |
| | | { |
| | | deleteTime = csn; |
| | | } |
| | | addTime = null; |
| | | lastMod = DEL; |
| | | value = null; |
| | | deleteWithoutDeleteTime(); |
| | | } |
| | | else |
| | | { |
| | |
| | | if (csn.isNewerThanOrEqualTo(deleteTime) |
| | | && (addTime == null || addTime.isOlderThan(deleteTime))) |
| | | { |
| | | // no conflict : don't do anything beside setting the addTime |
| | | addTime = csn; |
| | | value = newValue; |
| | | lastMod = ADD; |
| | | add(csn, newValue); |
| | | } |
| | | else |
| | | { |
| | |
| | | if (csn.equals(deleteTime) && csn.equals(addTime) |
| | | && lastMod == DEL) |
| | | { |
| | | // No conflict, record the new value. |
| | | value = newValue; |
| | | lastMod = ADD; |
| | | add(csn, newValue); |
| | | } |
| | | else |
| | | { |
| | |
| | | } |
| | | else |
| | | { |
| | | if (newValue == null) |
| | | { |
| | | addTime = null; |
| | | value = newValue; |
| | | deleteTime = csn; |
| | | lastMod = DEL; |
| | | } |
| | | else |
| | | { |
| | | addTime = csn; |
| | | value = newValue; |
| | | deleteTime = csn; |
| | | lastMod = REPL; |
| | | } |
| | | replaceOrDelete(csn, newValue); |
| | | } |
| | | break; |
| | | |