package fr.openwide.core.jpa.more.business.history.service;
import java.util.Date;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import com.google.common.base.Supplier;
import fr.openwide.core.jpa.business.generic.service.GenericEntityServiceImpl;
import fr.openwide.core.jpa.exception.SecurityServiceException;
import fr.openwide.core.jpa.exception.ServiceException;
import fr.openwide.core.jpa.more.business.difference.service.IDifferenceService;
import fr.openwide.core.jpa.more.business.difference.util.IDifferenceFromReferenceGenerator;
import fr.openwide.core.jpa.more.business.difference.util.IHistoryDifferenceGenerator;
import fr.openwide.core.jpa.more.business.history.dao.IGenericHistoryLogDao;
import fr.openwide.core.jpa.more.business.history.model.AbstractHistoryDifference;
import fr.openwide.core.jpa.more.business.history.model.AbstractHistoryLog;
import fr.openwide.core.jpa.more.business.history.model.bean.AbstractHistoryLogAdditionalInformationBean;
import fr.openwide.core.jpa.more.business.history.util.HistoryLogBeforeCommitTask;
import fr.openwide.core.jpa.more.business.history.util.HistoryLogBeforeCommitWithDifferencesTask;
import fr.openwide.core.jpa.more.business.history.util.IHistoryDifferenceHandler;
import fr.openwide.core.jpa.more.util.transaction.service.ITransactionSynchronizationTaskManagerService;
public abstract class AbstractHistoryLogServiceImpl<HL extends AbstractHistoryLog<HL, HET, HD>,
HET extends Enum<HET>,
HD extends AbstractHistoryDifference<HD, HL>,
HLAIB extends AbstractHistoryLogAdditionalInformationBean>
extends GenericEntityServiceImpl<Long, HL>
implements IGenericHistoryLogService<HL, HET, HD, HLAIB> {
@Autowired
protected ITransactionSynchronizationTaskManagerService transactionSynchronizationTaskManagerService;
@Autowired
protected IHistoryValueService valueService;
@Autowired
public AbstractHistoryLogServiceImpl(IGenericHistoryLogDao<HL, HET> dao) {
super(dao);
}
@Override
public <T> HL logNow(Date date, HET eventType, List<HD> differences, T mainObject, HLAIB additionalInformation)
throws ServiceException, SecurityServiceException {
HL log = newHistoryLog(date, eventType, differences, mainObject, additionalInformation);
log.setDifferences(differences);
for (HD difference : differences) {
difference.setParentLog(log);
}
create(log);
return log;
}
protected abstract <T> HL newHistoryLog(Date date, HET eventType, List<HD> differences, T mainObject, HLAIB additionalInformation);
protected abstract Supplier<HD> newHistoryDifferenceSupplier();
protected void setAdditionalInformation(HL log, HLAIB additionalInformation) {
if (additionalInformation != null) {
setAdditionalInformation(log, additionalInformation.getSecondaryObjects());
}
}
protected void setAdditionalInformation(HL log, Object[] objects) {
if (objects.length > 4) {
throw new IllegalArgumentException(String.format("Too many arguments (%d, expected %d or less)", objects.length, 4));
}
if (objects.length >= 1) {
log.setObject1(valueService.create(objects[0]));
}
if (objects.length >= 2) {
log.setObject2(valueService.create(objects[1]));
}
if (objects.length >= 3) {
log.setObject3(valueService.create(objects[2]));
}
if (objects.length >= 4) {
log.setObject4(valueService.create(objects[3]));
}
}
@Override
public <T> void log(HET eventType, T mainObject, HLAIB additionalInformation) throws ServiceException,
SecurityServiceException {
transactionSynchronizationTaskManagerService.push(
new HistoryLogBeforeCommitTask<T, HLAIB, HL, HET, HD>(new Date(), eventType, mainObject, additionalInformation)
);
}
@Override
public final <T> void logWithDifferences(HET eventType, T mainObject, HLAIB additionalInformation,
IDifferenceService<T> differenceService) throws ServiceException, SecurityServiceException {
logWithDifferences(eventType, mainObject, additionalInformation, differenceService.getMainDifferenceGenerator(),
differenceService);
}
@Override
@SafeVarargs
public final <T> void logWithDifferences(HET eventType, T mainObject, HLAIB additionalInformation,
IDifferenceService<T> differenceService, IHistoryDifferenceHandler<? super T, ? super HL> ... differenceHandlers)
throws ServiceException,
SecurityServiceException {
logWithDifferences(eventType, mainObject, additionalInformation, differenceService.getMainDifferenceGenerator(),
differenceService, differenceHandlers);
}
@Override
@SafeVarargs
public final <T> void logWithDifferences(HET eventType, T mainObject, HLAIB additionalInformation,
IDifferenceFromReferenceGenerator<T> differenceGenerator,
IHistoryDifferenceGenerator<T> historyDifferenceGenerator, IHistoryDifferenceHandler<? super T, ? super HL>... differenceHandlers)
throws ServiceException, SecurityServiceException {
transactionSynchronizationTaskManagerService.push(
new HistoryLogBeforeCommitWithDifferencesTask<T, HLAIB, HL, HET, HD>(
new Date(), eventType,
mainObject, additionalInformation,
newHistoryDifferenceSupplier(),
differenceGenerator, historyDifferenceGenerator, differenceHandlers
)
);
}
}