package regexgolf2.services.persistence; import regexgolf2.model.SolvableChallenge; import regexgolf2.model.Word; import regexgolf2.model.containers.ChallengePool; import regexgolf2.model.containers.ContainerChangedListener; import regexgolf2.model.containers.WordPool; import regexgolf2.services.persistence.changetracking.ChangeTrackingService; import regexgolf2.services.persistence.changetracking.PersistenceInformation; import regexgolf2.services.persistence.mappers.Mappers; import regexgolf2.services.persistence.saving.Savable; import regexgolf2.services.persistence.saving.SaveVisitorImpl; import com.google.java.contract.Ensures; import com.google.java.contract.Requires; public class PersistenceService { private final Mappers _mappers; private final ChangeTrackingService _changeTrackingService; private final TrackHandler _trackHandler; private final SaveVisitorImpl _saveVisitor; private final ChallengePool _challengePool; private final WordPool _wordPool; @Requires("mappers != null") public PersistenceService(Mappers mappers) throws PersistenceException { _mappers = mappers; _changeTrackingService = new ChangeTrackingService(); _trackHandler = new TrackHandler(_changeTrackingService); _saveVisitor = new SaveVisitorImpl(_changeTrackingService, _mappers); _challengePool = createChallengePool(); _wordPool = createWordPool(); } private WordPool createWordPool() throws PersistenceException { WordPool pool = new WordPool(); for (Word word : _mappers.getWordMapper().getAll()) { pool.add(word); _changeTrackingService.track(word, false); } ContainerChangedListener<Word> deleteHandler = new DeleteHandler<>(getPersistenceInformation(), word -> _mappers.getWordMapper().delete(word)); pool.addListener(event -> { deleteHandler.containerChanged(event); _trackHandler.containerChanged(event); }); return pool; } private ChallengePool createChallengePool() throws PersistenceException { ChallengePool pool = new ChallengePool(); for (SolvableChallenge challenge : _mappers.getSolvableChallengeMapper().getAll()) { pool.add(challenge); _changeTrackingService.track(challenge, false); } ContainerChangedListener<SolvableChallenge> deleteHandler = new DeleteHandler<>(getPersistenceInformation(), challenge -> _mappers.getSolvableChallengeMapper().delete(challenge)); // Because the deleteHandler needs to access PersistenceStates for // removed items, // the trackHandler needs to untrack the item after the // deleteHandler was called. pool.addListener(event -> { deleteHandler.containerChanged(event); _trackHandler.containerChanged(event); }); return pool; } @Requires("savable != null") public void save(Savable savable) throws PersistenceException { savable.accept(_saveVisitor); } @Ensures("result != null") public ChallengePool getChallengePool() { return _challengePool; } public WordPool getWordPool() { return _wordPool; } @Ensures("result != null") public PersistenceInformation getPersistenceInformation() { return _changeTrackingService; } }