package com.link_intersystems.gitdirstat.domain;
import java.io.IOException;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.TimeZone;
import org.apache.commons.collections4.IteratorUtils;
import org.apache.commons.collections4.Predicate;
import org.apache.commons.collections4.functors.AllPredicate;
import org.apache.commons.collections4.functors.FalsePredicate;
import org.apache.commons.collections4.functors.TruePredicate;
import org.eclipse.jgit.api.GitCommand;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.lib.PersonIdent;
import org.eclipse.jgit.lib.ReflogEntry;
import com.link_intersystems.lang.Assert;
public class ExpireReflogCommand extends GitCommand<Void> {
private GitRepository gitRepository;
private ReflogEntryFilter reflogEntryFilter = NullReflogEntryFilter.INSTANCE;
private Predicate<ReflogEntry> expireDatePredicate = FalsePredicate
.falsePredicate();
protected ExpireReflogCommand(GitRepository gitRepository) {
super(gitRepository.getRepository());
this.gitRepository = gitRepository;
setCallable(true);
}
public void setExpire(Date expireDate, TimeZone timeZone) {
Assert.notNull("expireDate", expireDate);
Assert.notNull("timeZone", timeZone);
if (expireDate == null) {
setExpire((Calendar) null);
} else {
Calendar expireCalendar = Calendar.getInstance(timeZone);
expireCalendar.setTime(expireDate);
setExpire(expireCalendar);
}
}
public void setExpire(Calendar expireCalendar) {
if (expireCalendar == null) {
this.expireDatePredicate = TruePredicate.truePredicate();
} else {
Calendar nowCalendar = Calendar.getInstance();
if (expireCalendar.after(nowCalendar)) {
String message = MessageFormat
.format("expire date {0,date,full} in time zone {1} must be in the"
+ " past according to the current date {2,date,full} in"
+ " time zone {3} or null",
expireCalendar.getTime(),
expireCalendar.getTimeZone(),
nowCalendar.getTime(),
nowCalendar.getTimeZone());
throw new IllegalArgumentException(message);
}
this.expireDatePredicate = new ExpireDateFilterPredicate(
expireCalendar);
}
}
public void setReflogEntryFilter(ReflogEntryFilter reflogEntryFilter) {
if (reflogEntryFilter == null) {
reflogEntryFilter = NullReflogEntryFilter.INSTANCE;
}
this.reflogEntryFilter = reflogEntryFilter;
}
@Override
public Void call() throws GitAPIException {
checkCallable();
List<Ref> refs = gitRepository.getRefs(Ref.class);
List<Predicate<ReflogEntry>> refLogEntryFilterPredicates = new ArrayList<Predicate<ReflogEntry>>();
refLogEntryFilterPredicates.add(expireDatePredicate);
refLogEntryFilterPredicates.add(new ReflogEntryFilterPredicateAdapter(
reflogEntryFilter));
Predicate<ReflogEntry> refLogEntriesFilter = AllPredicate
.allPredicate(refLogEntryFilterPredicates);
try {
for (Ref ref : refs) {
List<ReflogEntry> reflogEntries = ref.getReflogEntries();
Iterator<ReflogEntry> reflogEntryIterator = reflogEntries
.iterator();
Iterator<ReflogEntry> filteredReflogEntryIterator = IteratorUtils
.filteredIterator(reflogEntryIterator,
refLogEntriesFilter);
List<ReflogEntry> nonFilteredReflogEntries = IteratorUtils
.toList(filteredReflogEntryIterator);
ref.clearReflog();
ref.addReflogEntries(nonFilteredReflogEntries);
}
} catch (IOException e) {
throw new GitAPIException("Unable to read reflog entries", e) {
private static final long serialVersionUID = 2266798959465371684L;
};
}
return null;
}
public static interface ReflogEntryFilter {
public boolean accept(ReflogEntry reflogEntry);
}
private static class NullReflogEntryFilter implements ReflogEntryFilter {
private static final NullReflogEntryFilter INSTANCE = new NullReflogEntryFilter();
@Override
public boolean accept(ReflogEntry reflogEntry) {
return true;
}
}
private static class ReflogEntryFilterPredicateAdapter implements
Predicate<ReflogEntry> {
private ReflogEntryFilter reflogEntryFilter;
public ReflogEntryFilterPredicateAdapter(
ReflogEntryFilter reflogEntryFilter) {
this.reflogEntryFilter = reflogEntryFilter;
}
@Override
public boolean evaluate(ReflogEntry reflogEntry) {
return reflogEntryFilter.accept(reflogEntry);
}
}
private static class ExpireDateFilterPredicate implements
Predicate<ReflogEntry> {
private Calendar expireCalendar;
public ExpireDateFilterPredicate(Calendar expireCalendar) {
this.expireCalendar = expireCalendar;
}
@Override
public boolean evaluate(ReflogEntry reflogEntry) {
PersonIdent who = reflogEntry.getWho();
TimeZone timeZone = who.getTimeZone();
Calendar reflogEntryCalendar = Calendar.getInstance(timeZone);
Date when = who.getWhen();
reflogEntryCalendar.setTime(when);
boolean isNotExpired = reflogEntryCalendar.after(expireCalendar);
return isNotExpired;
}
}
}