Skip to content

Commit

Permalink
Merge pull request #48 from Thibstars/feature/47/Use-correct-language…
Browse files Browse the repository at this point in the history
…-in-iRail-API-calls
  • Loading branch information
Thibstars authored Sep 17, 2023
2 parents e5ae61b + 0490fb0 commit 7279b18
Show file tree
Hide file tree
Showing 15 changed files with 165 additions and 41 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,8 @@ public String getMessage(String key) {
public void initLocale() {
changeLocale(i18NService.getPreferredLocale());
}

public Locale getPrefferedLocale() {
return i18NService.getPreferredLocale();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,16 +46,17 @@ public void run() {
i18NController.addListener(stationsTable);
ReportIssueDialog reportIssueDialog = new ReportIssueDialog();
i18NController.addListener(reportIssueDialog);
i18NController.initLocale();

this.creatable = new Controllers(
new AboutController(propertiesService, aboutDialog),
liveBoardController,
new StationsController(stationsTable, services.stationService(), liveBoardController),
new StationsController(stationsTable, services.stationService(), liveBoardController, i18NController),
new ReportIssueController(propertiesService, reportIssueDialog),
i18NController
);

i18NController.initLocale();

completeTask(countDownLatchContext);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
import com.github.thibstars.btsd.internal.PropertiesServiceImpl;
import com.github.thibstars.btsd.irail.client.LiveBoardServiceImpl;
import com.github.thibstars.btsd.irail.client.StationServiceImpl;
import com.github.thibstars.btsd.irail.helper.LanguageService;
import com.github.thibstars.btsd.irail.helper.LanguageServiceImpl;
import okhttp3.OkHttpClient;

/**
Expand Down Expand Up @@ -38,10 +40,12 @@ public void run() {

PreferencesService preferencesService = new PreferencesServiceImpl();

LanguageService languageService = new LanguageServiceImpl();

this.creatable = new Services(
new PropertiesServiceImpl(),
new LiveBoardServiceImpl(okHttpClient, objectMapper),
new StationServiceImpl(okHttpClient, objectMapper),
new LiveBoardServiceImpl(okHttpClient, objectMapper, languageService),
new StationServiceImpl(okHttpClient, objectMapper, languageService),
preferencesService,
new I18NServiceImpl(preferencesService)
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public LiveBoardController(LiveBoardService liveBoardService, I18NController i18
}

public void showLiveBoardForStation(String id, Dimension dimension) {
liveBoardService.getForStation(id)
liveBoardService.getForStation(id, i18NController.getPrefferedLocale().getLanguage())
.ifPresent(liveBoard -> {
LiveBoardFrame liveBoardFrame = new LiveBoardFrame(liveBoard, dimension);
i18NController.addListener(liveBoardFrame);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.github.thibstars.btsd.desktop.stations;

import com.github.thibstars.btsd.desktop.i18n.I18NController;
import com.github.thibstars.btsd.desktop.liveboard.LiveBoardController;
import com.github.thibstars.btsd.irail.client.StationService;
import java.awt.Dimension;
Expand All @@ -14,14 +15,20 @@ public class StationsController {

private final StationsTable stationsTable;

private final StationService stationService;

private final LiveBoardController liveBoardController;

private final I18NController i18NController;

public StationsController(StationsTable stationsTable, StationService stationService,
LiveBoardController liveBoardController) {
LiveBoardController liveBoardController, I18NController i18NController) {
this.stationsTable = stationsTable;
this.stationService = stationService;
this.liveBoardController = liveBoardController;
this.i18NController = i18NController;

stationsTable.setStations(stationService.getStations());
stationsTable.init(this);
}

public void initStationsTable(Dimension dimension) {
Expand All @@ -44,4 +51,8 @@ public JScrollPane getStationsTableScrollPane() {
public void filterStationsTableByName(String name) {
stationsTable.filterStationsTableByName(name);
}

protected void fetchStations() {
stationsTable.setStations(stationService.getStations(i18NController.getPrefferedLocale().getLanguage()));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ public class StationsTable extends JTable implements LocaleChangeListener {

private transient Set<Station> stations;

private transient StationsController stationsController;

public StationsTable() throws HeadlessException {
model = new StationsTableModel();
model.addColumn("id");
Expand Down Expand Up @@ -62,10 +64,12 @@ protected void setStations(Set<Station> stations) {
this.stations = stations;
model.setRowCount(0);
stations.forEach(station -> model.addRow(new Object[] {station.id(), station.name()}));
model.fireTableDataChanged();
}

protected JScrollPane getScrollPane() {
JScrollPane spTable = new JScrollPane(this, ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
JScrollPane spTable = new JScrollPane(this, ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS,
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
spTable.setViewportView(this);

return spTable;
Expand All @@ -78,6 +82,8 @@ protected void filterStationsTableByName(String name) {

@Override
public void localeChanged(Locale locale, I18NController i18NController) {
stationsController.fetchStations();

model.setColumnIdentifiers(
List.of(
i18NController.getMessage("station.id"),
Expand All @@ -89,5 +95,12 @@ public void localeChanged(Locale locale, I18NController i18NController) {

List<SortKey> sortKeys = List.of(new RowSorter.SortKey(1, SortOrder.ASCENDING));
sorter.setSortKeys(sortKeys);

stationsController.fetchStations();
}

public void init(StationsController stationsController) {
this.stationsController = stationsController;
stationsController.fetchStations();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@ public interface LiveBoardService {
/**
* Retrieves a Live Board for a given Station.
*
* @param id the Station's id
* @param id the Station's id
* @param language the language to use
* @return a Live Board for a given Station
*/
Optional<LiveBoard> getForStation(String id);
Optional<LiveBoard> getForStation(String id, String language);
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.thibstars.btsd.irail.exceptions.ClientException;
import com.github.thibstars.btsd.irail.helper.LanguageService;
import com.github.thibstars.btsd.irail.model.LiveBoard;
import java.io.IOException;
import java.util.Objects;
Expand All @@ -20,31 +21,38 @@ public class LiveBoardServiceImpl implements LiveBoardService {

private static final Logger LOGGER = LoggerFactory.getLogger(LiveBoardServiceImpl.class);

private static final String URL = "https://api.irail.be/liveboard/?id=${id}&arrdep=departure&lang=en&format=json&alerts=false";
private static final String ID_PLACEHOLDER = "${id}";

private static final String LANG_PLACEHOLDER = "${lang}";

private static final String URL = "https://api.irail.be/liveboard/?id=" + ID_PLACEHOLDER + "&arrdep=departure&lang=" + LANG_PLACEHOLDER + "&format=json&alerts=false";

private final OkHttpClient client;

private final ObjectMapper objectMapper;

public LiveBoardServiceImpl(OkHttpClient client, ObjectMapper objectMapper) {
private final LanguageService languageService;

public LiveBoardServiceImpl(OkHttpClient client, ObjectMapper objectMapper, LanguageService languageService) {
this.client = client;
this.objectMapper = objectMapper;
this.languageService = languageService;
}

@Override
public Optional<LiveBoard> getForStation(String id) {
public Optional<LiveBoard> getForStation(String id, String language) {
try {
return Optional.of(fetchLiveBoard(id));
return Optional.of(fetchLiveBoard(id, language));
} catch (IOException e) {
throw new ClientException(e);
}
}

private LiveBoard fetchLiveBoard(String id) throws IOException {
private LiveBoard fetchLiveBoard(String id, String language) throws IOException {
LOGGER.info("Fetching live board for station: {}", id);

Request request = new Request.Builder()
.url(URL.replace("${id}", id))
.url(URL.replace(ID_PLACEHOLDER, id).replace(LANG_PLACEHOLDER, languageService.getLanguageOrFallback(language)))
.build();

ResponseBody responseBody;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,6 @@ public interface StationService {
*
* @return a set of all available Stations
*/
Set<Station> getStations();
Set<Station> getStations(String language);

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@

import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.thibstars.btsd.irail.exceptions.ClientException;
import com.github.thibstars.btsd.irail.helper.LanguageService;
import com.github.thibstars.btsd.irail.model.Station;
import com.github.thibstars.btsd.irail.model.Stations;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Objects;
Expand All @@ -30,55 +32,70 @@ public class StationServiceImpl implements StationService {

private static final Logger LOGGER = LoggerFactory.getLogger(StationServiceImpl.class);

private static final String URL = "https://api.irail.be/stations?format=json&lang=en";
private static final String LANG_PLACEHOLDER = "${lang}";

private static final String URL = "https://api.irail.be/stations?format=json&lang=" + LANG_PLACEHOLDER;

private final OkHttpClient client;

private final ObjectMapper objectMapper;

private final LoadingCache<String, Station> cache;
private final LanguageService languageService;

private final LoadingCache<String, Map<String, Station>> cache;

public StationServiceImpl(OkHttpClient client, ObjectMapper objectMapper) {
public StationServiceImpl(OkHttpClient client, ObjectMapper objectMapper, LanguageService languageService) {
this.client = client;
this.objectMapper = objectMapper;
CacheLoader<String, Station> loader = new CacheLoader<>() {
this.languageService = languageService;
CacheLoader<String, Map<String, Station>> loader = new CacheLoader<>() {
@NotNull
@Override
public Station load(@NotNull String key) throws Exception {
public Map<String, Station> load(@NotNull String key) throws Exception {
return cache.get(key);
}

@NotNull
@Override
public Map<String, Station> loadAll(@NotNull Iterable<? extends String> keys) {
return getStations().stream()
.collect(Collectors.toMap(Station::id, Function.identity()));
public Map<String, Map<String, Station>> loadAll(@NotNull Iterable<? extends String> keys) {
return getAllStations();
}
};

cache = CacheBuilder.newBuilder()
.build(loader);

try {
cache.putAll(
fetchStations().stream()
.collect(Collectors.toMap(Station::id, Function.identity()))
);
cache.putAll(fetchAllStations());
} catch (IOException e) {
throw new ClientException(e);
}
}

@Override
public Set<Station> getStations() {
return new HashSet<>(cache.asMap().values());
public Set<Station> getStations(String language) {
return new HashSet<>(cache.getUnchecked(languageService.getLanguageOrFallback(language)).values());
}

private Map<String, Map<String, Station>> getAllStations() {
return cache.getAllPresent(languageService.getSupportedLanguages());
}

private Map<String, Map<String, Station>> fetchAllStations() throws IOException {
Map<String, Map<String, Station>> stationMap = new HashMap<>();

for (String language : languageService.getSupportedLanguages()) {
stationMap.put(language, fetchStations(language));
}

return stationMap;
}

private Set<Station> fetchStations() throws IOException {
LOGGER.info("Fetching stations.");
private Map<String, Station> fetchStations(String language) throws IOException {
LOGGER.info("Fetching stations for language: {}", language);

Request request = new Request.Builder()
.url(URL)
.url(URL.replace(LANG_PLACEHOLDER, language))
.build();

ResponseBody responseBody;
Expand All @@ -88,6 +105,9 @@ private Set<Station> fetchStations() throws IOException {
stations = objectMapper.readValue(responseBody.string(), Stations.class);
}

return stations != null ? stations.stations() : Collections.emptySet();
return stations != null ?
stations.stations().stream()
.collect(Collectors.toMap(Station::id, Function.identity())) :
Collections.emptyMap();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.github.thibstars.btsd.irail.helper;

import java.util.Set;

/**
* @author Thibault Helsmoortel
*/
public interface LanguageService {

Set<String> getSupportedLanguages();

String getLanguageOrFallback(String language);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package com.github.thibstars.btsd.irail.helper;

import java.util.Optional;
import java.util.Set;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* @author Thibault Helsmoortel
*/
public class LanguageServiceImpl implements LanguageService {

private static final Logger LOGGER = LoggerFactory.getLogger(LanguageServiceImpl.class);

private static final Set<String> SUPPORTED_LANGS = Set.of("en", "nl", "fr", "de");


@Override
public Set<String> getSupportedLanguages() {
return SUPPORTED_LANGS;
}

@Override
public String getLanguageOrFallback(String language) {
Optional<String> optionalLanguage = SUPPORTED_LANGS.stream()
.filter(lang -> lang.equals(language))
.findFirst();

String fallbackLanguage = SUPPORTED_LANGS.stream().findFirst().orElseThrow();
if (optionalLanguage.isEmpty()) {
LOGGER.warn("Language {} is not supported, using {} as a fallback.", language, fallbackLanguage);
}

return optionalLanguage.orElse(fallbackLanguage);
}
}
Loading

0 comments on commit 7279b18

Please sign in to comment.