Skip to content

Commit

Permalink
#16 Refactoring: extract Storage interface
Browse files Browse the repository at this point in the history
  • Loading branch information
kaklakariada committed Nov 28, 2020
1 parent 47d5023 commit 89a2673
Show file tree
Hide file tree
Showing 9 changed files with 99 additions and 89 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,36 +16,20 @@

public class AutocompleteService
{
private final MonthCache monthCache;
private final Storage storage;

private boolean cacheInitialized = false;

public AutocompleteService(Storage storage, MonthCache monthCache)
public AutocompleteService(Storage storage)
{
this.storage = storage;
this.monthCache = monthCache;
}

private void ensureCacheInitialized()
{
if (cacheInitialized)
{
return;
}
storage.loadAll();
cacheInitialized = true;
}

public AutocompleteEntrySupplier dayCommentAutocompleter()
{
ensureCacheInitialized();
return autocompleter(asList("blah", "blubb", "abc", "cyasd"));
}

public AutocompleteEntrySupplier activityCommentAutocompleter()
{
ensureCacheInitialized();
return autocompleter(asList("blah", "blubb", "abc", "cyasd"));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
import org.apache.logging.log4j.Logger;
import org.itsallcode.whiterabbit.logic.Config;
import org.itsallcode.whiterabbit.logic.autocomplete.AutocompleteService;
import org.itsallcode.whiterabbit.logic.autocomplete.MonthCache;
import org.itsallcode.whiterabbit.logic.model.DayRecord;
import org.itsallcode.whiterabbit.logic.model.MonthIndex;
import org.itsallcode.whiterabbit.logic.service.AppPropertiesService.AppProperties;
Expand Down Expand Up @@ -88,10 +87,8 @@ public static AppService create(final Config config, Clock clock, ScheduledExecu
final SingleInstanceService singleInstanceService = SingleInstanceService.create(config);
final ProjectService projectService = new ProjectService(config);

final MonthCache monthCache = new MonthCache();
final Storage storage = Storage.create(config.getDataDir(), new ContractTermsService(config), projectService,
monthCache::update);
final AutocompleteService autocompleteService = new AutocompleteService(storage, monthCache);
final Storage storage = Storage.create(config.getDataDir(), new ContractTermsService(config), projectService);
final AutocompleteService autocompleteService = new AutocompleteService(storage);
final ClockService clockService = new ClockService(clock);
final SchedulingService schedulingService = new SchedulingService(clockService, scheduledExecutor);
final DelegatingAppServiceCallback appServiceCallback = new DelegatingAppServiceCallback();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package org.itsallcode.whiterabbit.logic.storage;

import java.time.YearMonth;
import java.util.List;
import java.util.Optional;

import org.itsallcode.whiterabbit.logic.model.MonthIndex;
import org.itsallcode.whiterabbit.logic.model.MultiMonthIndex;

class CachingStorage implements Storage
{
private final Storage delegateStorage;
private final MonthCache cache;

CachingStorage(Storage delegateStorage)
{
this(delegateStorage, new MonthCache());
}

CachingStorage(Storage delegateStorage, MonthCache cache)
{
this.delegateStorage = delegateStorage;
this.cache = cache;
}

@Override
public Optional<MonthIndex> loadMonth(YearMonth date)
{
return delegateStorage.loadMonth(date).map(this::updateCache);
}

@Override
public MonthIndex loadOrCreate(final YearMonth yearMonth)
{
return updateCache(delegateStorage.loadOrCreate(yearMonth));
}

@Override
public void storeMonth(MonthIndex month)
{
delegateStorage.storeMonth(updateCache(month));
}

@Override
public MultiMonthIndex loadAll()
{
return updateCache(delegateStorage.loadAll());
}

private MultiMonthIndex updateCache(MultiMonthIndex index)
{
index.getMonths().forEach(this::updateCache);
return index;
}

private MonthIndex updateCache(MonthIndex month)
{
cache.update(month);
return month;
}

@Override
public List<YearMonth> getAvailableDataYearMonth()
{
return delegateStorage.getAvailableDataYearMonth();
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package org.itsallcode.whiterabbit.logic.autocomplete;
package org.itsallcode.whiterabbit.logic.storage;

import static java.util.stream.Collectors.toList;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
import org.itsallcode.whiterabbit.logic.service.contract.ContractTermsService;
import org.itsallcode.whiterabbit.logic.service.project.ProjectService;

class MonthIndexStorage
class MonthIndexStorage implements Storage
{
private static final Logger LOG = LogManager.getLogger(MonthIndexStorage.class);

Expand All @@ -33,30 +33,35 @@ class MonthIndexStorage
this.fileStorage = fileStorage;
}

Optional<MonthIndex> loadMonth(YearMonth date)
@Override
public Optional<MonthIndex> loadMonth(YearMonth date)
{
return fileStorage.loadMonthRecord(date).map(this::createMonthIndex);
}

MonthIndex loadOrCreate(final YearMonth yearMonth)
@Override
public MonthIndex loadOrCreate(final YearMonth yearMonth)
{
final Optional<MonthIndex> month = loadMonth(yearMonth);
return month.orElseGet(() -> createNewMonth(yearMonth));
}

void storeMonth(MonthIndex month)
@Override
public void storeMonth(MonthIndex month)
{
fileStorage.writeToFile(month.getYearMonth(), month.getMonthRecord());
}

MultiMonthIndex loadAll()
@Override
public MultiMonthIndex loadAll()
{
return new MultiMonthIndex(fileStorage.loadAll().stream()
.map(this::createMonthIndex)
.collect(toList()));
}

List<YearMonth> getAvailableDataYearMonth()
@Override
public List<YearMonth> getAvailableDataYearMonth()
{
return fileStorage.getAvailableDataYearMonth();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,61 +14,26 @@
import org.itsallcode.whiterabbit.logic.service.contract.ContractTermsService;
import org.itsallcode.whiterabbit.logic.service.project.ProjectService;

public class Storage
public interface Storage
{
private final StorageLoadingListener loadingListener;
private final MonthIndexStorage monthIndexStorage;

Storage(MonthIndexStorage monthIndexStorage, StorageLoadingListener loadingListener)
{
this.monthIndexStorage = monthIndexStorage;
this.loadingListener = loadingListener;
}

public static Storage create(Path dataDir, ContractTermsService contractTerms,
ProjectService projectService, StorageLoadingListener loadingListener)
public static Storage create(Path dataDir, ContractTermsService contractTerms, ProjectService projectService)
{
final DateToFileMapper dateToFileMapper = new DateToFileMapper(dataDir);
final Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().withFormatting(true));
final JsonFileStorage fileStorage = new JsonFileStorage(jsonb, dateToFileMapper);
final MonthIndexStorage monthIndexStorage = new MonthIndexStorage(contractTerms, projectService, fileStorage);
return new Storage(monthIndexStorage, loadingListener);
return new CachingStorage(monthIndexStorage);
}

public Optional<MonthIndex> loadMonth(YearMonth date)
{
return monthIndexStorage.loadMonth(date).map(this::updateCache);
}
Optional<MonthIndex> loadMonth(YearMonth date);

public MonthIndex loadOrCreate(final YearMonth yearMonth)
{
return updateCache(monthIndexStorage.loadOrCreate(yearMonth));
}

public void storeMonth(MonthIndex month)
{
monthIndexStorage.storeMonth(updateCache(month));
}
MonthIndex loadOrCreate(YearMonth yearMonth);

public MultiMonthIndex loadAll()
{
return updateCache(monthIndexStorage.loadAll());
}
void storeMonth(MonthIndex month);

private MultiMonthIndex updateCache(MultiMonthIndex index)
{
index.getMonths().forEach(this::updateCache);
return index;
}
MultiMonthIndex loadAll();

private MonthIndex updateCache(MonthIndex month)
{
loadingListener.monthLoaded(month);
return month;
}
List<YearMonth> getAvailableDataYearMonth();

public List<YearMonth> getAvailableDataYearMonth()
{
return monthIndexStorage.getAvailableDataYearMonth();
}
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,12 @@
import org.mockito.junit.jupiter.MockitoExtension;

@ExtendWith(MockitoExtension.class)
class StorageTest
class CachingStorageTest
{
private static final YearMonth YEAR_MONTH = YearMonth.of(2020, Month.NOVEMBER);

@Mock
StorageLoadingListener loadingListenerMock;
MonthCache cacheMock;
@Mock
MonthIndexStorage monthIndexStorageMock;
@Mock
Expand All @@ -38,7 +38,7 @@ class StorageTest
@BeforeEach
void setUp()
{
storage = new Storage(monthIndexStorageMock, loadingListenerMock);
storage = new CachingStorage(monthIndexStorageMock, cacheMock);
}

@Test
Expand All @@ -56,7 +56,7 @@ void loadMonth_doesNotUpdateCache_whenMonthNotFound()
when(monthIndexStorageMock.loadMonth(YEAR_MONTH)).thenReturn(Optional.empty());
storage.loadMonth(YEAR_MONTH);

verifyNoInteractions(loadingListenerMock);
verifyNoInteractions(cacheMock);
}

@Test
Expand Down Expand Up @@ -89,12 +89,12 @@ void loadAll_doesNotUpdateCache_whenNoEntriesFound()
when(monthIndexStorageMock.loadAll()).thenReturn(new MultiMonthIndex(emptyList()));

storage.loadAll();
verifyNoInteractions(loadingListenerMock);
verifyNoInteractions(cacheMock);
}

private void verifyListenerUpdated()
{
verify(loadingListenerMock).monthLoaded(same(monthIndexMock));
verify(cacheMock).update(same(monthIndexMock));
}

@Test
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package org.itsallcode.whiterabbit.logic.autocomplete;
package org.itsallcode.whiterabbit.logic.storage;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
Expand All @@ -11,6 +11,7 @@

import org.itsallcode.whiterabbit.logic.model.DayRecord;
import org.itsallcode.whiterabbit.logic.model.MonthIndex;
import org.itsallcode.whiterabbit.logic.storage.MonthCache;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

Expand Down

0 comments on commit 89a2673

Please sign in to comment.