From 7d8d6dad9e8ed6e9d2ebc89da4d220e011b0e8f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6nke=20K=C3=BCper?= Date: Sun, 28 Nov 2021 13:49:57 +0100 Subject: [PATCH] Applied some review remarks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Sönke Küper --- .../README.md | 12 +- .../org.openhab.binding.deutschebahn/pom.xml | 2 +- ...y.java => DeutscheBahnHandlerFactory.java} | 4 +- .../DeutscheBahnTimetableHandler.java | 62 ++-- .../internal/DeutscheBahnTrainHandler.java | 2 +- .../main/resources/OH-INF/binding/binding.xml | 2 +- .../resources/OH-INF/thing/thing-types.xml | 33 +- .../DeutscheBahnTimetableHandlerTest.java | 84 +++++- .../DeutscheBahnTrainHandlerTest.java | 5 + .../timetable/TimetablesV1ApiStub.java | 71 +++++ .../timetablesData/plan/8000152/211014/11.xml | 283 +++++++++++++++++- 11 files changed, 513 insertions(+), 47 deletions(-) rename bundles/org.openhab.binding.deutschebahn/src/main/java/org/openhab/binding/deutschebahn/internal/{DeutscheBahnTimetableHandlerFactory.java => DeutscheBahnHandlerFactory.java} (91%) create mode 100644 bundles/org.openhab.binding.deutschebahn/src/test/java/org/openhab/binding/deutschebahn/internal/timetable/TimetablesV1ApiStub.java diff --git a/bundles/org.openhab.binding.deutschebahn/README.md b/bundles/org.openhab.binding.deutschebahn/README.md index 4d3141700cd86..23184d523fea2 100644 --- a/bundles/org.openhab.binding.deutschebahn/README.md +++ b/bundles/org.openhab.binding.deutschebahn/README.md @@ -1,7 +1,7 @@ -# DeutscheBahn Binding +# Deutsche Bahn Binding -The DeutscheBahn Binding provides the latest timetable information for all trains that arrive or depart at a specific train station, including live information for delays and changes in timetable. -The information are requested from the timetable api of DeutscheBahn developer portal, so you'll need a (free) developer account to use this binding. +The Deutsche Bahn Binding provides the latest timetable information for all trains that arrive or depart at a specific train station, including live information for delays and changes in timetable. +The information are requested from the timetable api of Deutsche Bahn developer portal, so you'll need a (free) developer account to use this binding. ## Supported Things @@ -12,9 +12,9 @@ The information are requested from the timetable api of DeutscheBahn developer p ### Generate Access-Key for timetable API -To configure a timetable you first need to register at DeutscheBahn developer portal and register for timetable API to get an access key. +To configure a timetable you first need to register at Deutsche Bahn developer portal and register for timetable API to get an access key. -1. Go to [DeutscheBahn Developer](https://developer.deutschebahn.com) +1. Go to [Deutsche Bahn Developer](https://developer.deutschebahn.com) 2. Register new account or login with an existing one 3. If no application is configured yet (check Tab "Meine Anwendungen") create a new application. Only the name is required, any other fields can be left blank. 4. Go to APIs - Timetables v1 (may be displayed on second page) @@ -37,7 +37,7 @@ In addition you can configure if only arrivals, only departures or all trains sh | Property | Default | Required | Description | |-|-|-|-| -| `accessToken` | | Yes | The access token for the timetable api within the developer portal of DeutscheBahn. | +| `accessToken` | | Yes | The access token for the timetable api within the developer portal of Deutsche Bahn. | | `evaNo` | | Yes | The eva nr. of the train station for which the timetable will be requested.| | `trainFilter` | | Yes | Selects the trains that will be displayed in the timetable. Either only arrivals, only departures or all trains can be displayed. | diff --git a/bundles/org.openhab.binding.deutschebahn/pom.xml b/bundles/org.openhab.binding.deutschebahn/pom.xml index de1b8d95d8082..48ddb0006be01 100644 --- a/bundles/org.openhab.binding.deutschebahn/pom.xml +++ b/bundles/org.openhab.binding.deutschebahn/pom.xml @@ -12,7 +12,7 @@ org.openhab.binding.deutschebahn - openHAB Add-ons :: Bundles :: DeutscheBahn Binding + openHAB Add-ons :: Bundles :: Deutsche Bahn Binding diff --git a/bundles/org.openhab.binding.deutschebahn/src/main/java/org/openhab/binding/deutschebahn/internal/DeutscheBahnTimetableHandlerFactory.java b/bundles/org.openhab.binding.deutschebahn/src/main/java/org/openhab/binding/deutschebahn/internal/DeutscheBahnHandlerFactory.java similarity index 91% rename from bundles/org.openhab.binding.deutschebahn/src/main/java/org/openhab/binding/deutschebahn/internal/DeutscheBahnTimetableHandlerFactory.java rename to bundles/org.openhab.binding.deutschebahn/src/main/java/org/openhab/binding/deutschebahn/internal/DeutscheBahnHandlerFactory.java index 5434a2a732d89..059f6b4dc53df 100644 --- a/bundles/org.openhab.binding.deutschebahn/src/main/java/org/openhab/binding/deutschebahn/internal/DeutscheBahnTimetableHandlerFactory.java +++ b/bundles/org.openhab.binding.deutschebahn/src/main/java/org/openhab/binding/deutschebahn/internal/DeutscheBahnHandlerFactory.java @@ -30,13 +30,13 @@ import org.osgi.service.component.annotations.Component; /** - * The {@link DeutscheBahnTimetableHandlerFactory} is responsible for creating things and thing handlers. + * The {@link DeutscheBahnHandlerFactory} is responsible for creating things and thing handlers. * * @author Sönke Küper - Initial contribution */ @NonNullByDefault @Component(configurationPid = "binding.deutschebahn", service = ThingHandlerFactory.class) -public class DeutscheBahnTimetableHandlerFactory extends BaseThingHandlerFactory { +public class DeutscheBahnHandlerFactory extends BaseThingHandlerFactory { private static final Set SUPPORTED_THING_TYPES_UIDS = Set.of(TIMETABLE_TYPE, TRAIN_TYPE); diff --git a/bundles/org.openhab.binding.deutschebahn/src/main/java/org/openhab/binding/deutschebahn/internal/DeutscheBahnTimetableHandler.java b/bundles/org.openhab.binding.deutschebahn/src/main/java/org/openhab/binding/deutschebahn/internal/DeutscheBahnTimetableHandler.java index e097bf9d8ec19..616493a999157 100644 --- a/bundles/org.openhab.binding.deutschebahn/src/main/java/org/openhab/binding/deutschebahn/internal/DeutscheBahnTimetableHandler.java +++ b/bundles/org.openhab.binding.deutschebahn/src/main/java/org/openhab/binding/deutschebahn/internal/DeutscheBahnTimetableHandler.java @@ -36,6 +36,7 @@ import org.openhab.binding.deutschebahn.internal.timetable.dto.TimetableStop; import org.openhab.core.io.net.http.HttpUtil; import org.openhab.core.thing.Bridge; +import org.openhab.core.thing.Channel; import org.openhab.core.thing.ChannelUID; import org.openhab.core.thing.Thing; import org.openhab.core.thing.ThingStatus; @@ -44,6 +45,7 @@ import org.openhab.core.thing.binding.BaseBridgeHandler; import org.openhab.core.thing.binding.ThingHandler; import org.openhab.core.types.Command; +import org.openhab.core.types.UnDefType; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.xml.sax.SAXException; @@ -100,7 +102,6 @@ public int getMaxPosition() { private @Nullable ScheduledFuture updateJob; private final Logger logger = LoggerFactory.getLogger(DeutscheBahnTimetableHandler.class); - private @Nullable DeutscheBahnTimetableConfiguration config; private @Nullable TimetableLoader loader; private TimetablesV1ApiFactory timetablesV1ApiFactory; @@ -112,7 +113,7 @@ public int getMaxPosition() { */ public DeutscheBahnTimetableHandler( // final Bridge bridge, // - TimetablesV1ApiFactory timetablesV1ApiFactory, // + final TimetablesV1ApiFactory timetablesV1ApiFactory, // final Supplier currentTimeProvider) { super(bridge); this.timetablesV1ApiFactory = timetablesV1ApiFactory; @@ -120,14 +121,14 @@ public DeutscheBahnTimetableHandler( // } private List loadTimetable() { - if (this.loader == null) { - this.updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR); + final TimetableLoader currentLoader = this.loader; + if (currentLoader == null) { + this.updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.HANDLER_INITIALIZING_ERROR); return Collections.emptyList(); } try { - @SuppressWarnings("null") - final List stops = this.loader.getTimetableStops(); + final List stops = currentLoader.getTimetableStops(); this.updateStatus(ThingStatus.ONLINE); return stops; } catch (final IOException e) { @@ -143,16 +144,14 @@ private List loadTimetable() { public void handleCommand(final ChannelUID channelUID, final Command command) { } - @SuppressWarnings("null") @Override public void initialize() { - this.config = this.getConfigAs(DeutscheBahnTimetableConfiguration.class); + final DeutscheBahnTimetableConfiguration config = this.getConfigAs(DeutscheBahnTimetableConfiguration.class); try { - final TimetablesV1Api api = this.timetablesV1ApiFactory.create(this.config.accessToken, - HttpUtil::executeUrl); + final TimetablesV1Api api = this.timetablesV1ApiFactory.create(config.accessToken, HttpUtil::executeUrl); - final TimetableStopFilter stopFilter = this.config.getTimetableStopFilter(); + final TimetableStopFilter stopFilter = config.getTimetableStopFilter(); final EventType eventSelection = stopFilter == TimetableStopFilter.ARRIVALS ? EventType.ARRIVAL : EventType.ARRIVAL; @@ -162,7 +161,7 @@ public void initialize() { stopFilter, // eventSelection, // currentTimeProvider, // - this.config.evaNo, // + config.evaNo, // 1); // will be updated on first call this.updateStatus(ThingStatus.UNKNOWN); @@ -173,7 +172,7 @@ public void initialize() { }); } catch (JAXBException | SAXException | URISyntaxException e) { this.logger.error("Error initializing api", e); - this.updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR); + this.updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, e.getMessage()); } } @@ -221,16 +220,17 @@ private void stopUpdateJob() { } } - @SuppressWarnings("null") private void updateChannels() { - if (this.loader == null) { - this.updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR); + final TimetableLoader currentLoader = this.loader; + if (currentLoader == null) { + this.updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.HANDLER_INITIALIZING_ERROR); return; } final GroupedThings groupedThings = this.groupThingsPerPosition(); - this.loader.setStopCount(groupedThings.getMaxPosition()); + currentLoader.setStopCount(groupedThings.getMaxPosition()); final List timetableStops = this.loadTimetable(); if (timetableStops.isEmpty()) { + updateThingsToUndefined(groupedThings); return; } @@ -238,6 +238,23 @@ private void updateChannels() { this.updateThings(groupedThings, timetableStops); } + /** + * No data was retrieved, so update all channel values to undefined. + */ + private void updateThingsToUndefined(GroupedThings groupedThings) { + for (List things : groupedThings.thingsPerPosition.values()) { + for (Thing thing : things) { + updateChannelsToUndefined(thing); + } + } + } + + private void updateChannelsToUndefined(Thing thing) { + for (Channel channel : thing.getChannels()) { + this.updateState(channel.getUID(), UnDefType.UNDEF); + } + } + private void updateThings(GroupedThings groupedThings, final List timetableStops) { int position = 1; for (final TimetableStop stop : timetableStops) { @@ -254,6 +271,17 @@ private void updateThings(GroupedThings groupedThings, final List } position++; } + + // Update all things to undefined, for which no data was received. + while (position <= groupedThings.getMaxPosition()) { + final List thingsAtPosition = groupedThings.getThingsAtPosition(position); + if (thingsAtPosition != null) { + for (Thing thing : thingsAtPosition) { + updateChannelsToUndefined(thing); + } + } + position++; + } } /** diff --git a/bundles/org.openhab.binding.deutschebahn/src/main/java/org/openhab/binding/deutschebahn/internal/DeutscheBahnTrainHandler.java b/bundles/org.openhab.binding.deutschebahn/src/main/java/org/openhab/binding/deutschebahn/internal/DeutscheBahnTrainHandler.java index 4a0a7001080e2..0652c8fd33eb9 100644 --- a/bundles/org.openhab.binding.deutschebahn/src/main/java/org/openhab/binding/deutschebahn/internal/DeutscheBahnTrainHandler.java +++ b/bundles/org.openhab.binding.deutschebahn/src/main/java/org/openhab/binding/deutschebahn/internal/DeutscheBahnTrainHandler.java @@ -102,7 +102,7 @@ public void initialize() { this.updateStatus(ThingStatus.UNKNOWN); if (this.getBridge() == null) { - this.updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR); + this.updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, "Please select bridge"); return; } diff --git a/bundles/org.openhab.binding.deutschebahn/src/main/resources/OH-INF/binding/binding.xml b/bundles/org.openhab.binding.deutschebahn/src/main/resources/OH-INF/binding/binding.xml index bca9006df6025..7deb3797ee87c 100644 --- a/bundles/org.openhab.binding.deutschebahn/src/main/resources/OH-INF/binding/binding.xml +++ b/bundles/org.openhab.binding.deutschebahn/src/main/resources/OH-INF/binding/binding.xml @@ -3,7 +3,7 @@ xmlns:binding="https://openhab.org/schemas/binding/v1.0.0" xsi:schemaLocation="https://openhab.org/schemas/binding/v1.0.0 https://openhab.org/schemas/binding-1.0.0.xsd"> - DeutscheBahn Binding + Deutsche Bahn Binding This binding provides timetable information for train stations of Deutsche Bahn. diff --git a/bundles/org.openhab.binding.deutschebahn/src/main/resources/OH-INF/thing/thing-types.xml b/bundles/org.openhab.binding.deutschebahn/src/main/resources/OH-INF/thing/thing-types.xml index 37039ba73313e..d85a7c028ebac 100644 --- a/bundles/org.openhab.binding.deutschebahn/src/main/resources/OH-INF/thing/thing-types.xml +++ b/bundles/org.openhab.binding.deutschebahn/src/main/resources/OH-INF/thing/thing-types.xml @@ -6,24 +6,24 @@ - - Connection to the timetable API of DeutscheBahn. Provides timetable data that can be displayed using the + + Connection to the timetable API of Deutsche Bahn. Provides timetable data that can be displayed using the train things. - Access Token from DeutscheBahn developer portal for accessing the webservice api. + Access Token from Deutsche Bahn developer portal for accessing the webservice api. - + evaNo of the station, for which the timetable should be requested. see https://data.deutschebahn.com/dataset.tags.EVA-Nr..html true departures - + Selects the trains that will be be displayed in this timetable. If not set only departures will be provided. @@ -127,14 +127,14 @@ String - + Provides the filter flags. String - + Provides the type of the trip. @@ -265,8 +265,9 @@ Switch - On if the event should not be shown on WBT because travellers are not supposed to enter or exit the train - at this stop. + On if the event should not be shown, because travellers are not supposed to enter or exit the train + at + this stop. @@ -287,21 +288,21 @@ String - + Planned distant endpoint. String - + Changed distant endpoint. Number - + distant change @@ -309,14 +310,14 @@ String - + Planned final station of the train. For arrivals the starting station is returned, for departures the target station is returned. String - + Returns the planned stations this train came from (for arrivals) or the stations this train will go to (for departures). Stations will be separated by single dash. @@ -324,7 +325,7 @@ String - + Changed final station of the train. For arrivals the starting station is returned, for departures the target station is returned. @@ -332,7 +333,7 @@ String - + Returns the changed stations this train came from (for arrivals) or the stations this train will go to (for departures). Stations will be separated by single dash. diff --git a/bundles/org.openhab.binding.deutschebahn/src/test/java/org/openhab/binding/deutschebahn/internal/DeutscheBahnTimetableHandlerTest.java b/bundles/org.openhab.binding.deutschebahn/src/test/java/org/openhab/binding/deutschebahn/internal/DeutscheBahnTimetableHandlerTest.java index f311d4f69fc84..5209ad9d283e9 100644 --- a/bundles/org.openhab.binding.deutschebahn/src/test/java/org/openhab/binding/deutschebahn/internal/DeutscheBahnTimetableHandlerTest.java +++ b/bundles/org.openhab.binding.deutschebahn/src/test/java/org/openhab/binding/deutschebahn/internal/DeutscheBahnTimetableHandlerTest.java @@ -23,14 +23,22 @@ import org.eclipse.jdt.annotation.NonNullByDefault; import org.junit.jupiter.api.Test; import org.openhab.binding.deutschebahn.internal.timetable.TimeproviderStub; +import org.openhab.binding.deutschebahn.internal.timetable.TimetablesV1ApiFactory; +import org.openhab.binding.deutschebahn.internal.timetable.TimetablesV1ApiStub; +import org.openhab.binding.deutschebahn.internal.timetable.TimetablesV1Impl.HttpCallable; import org.openhab.binding.deutschebahn.internal.timetable.TimetablesV1ImplTestHelper; +import org.openhab.binding.deutschebahn.internal.timetable.dto.Event; +import org.openhab.binding.deutschebahn.internal.timetable.dto.Timetable; import org.openhab.binding.deutschebahn.internal.timetable.dto.TimetableStop; import org.openhab.core.config.core.Configuration; import org.openhab.core.thing.Bridge; +import org.openhab.core.thing.Channel; import org.openhab.core.thing.Thing; import org.openhab.core.thing.ThingStatus; import org.openhab.core.thing.ThingUID; import org.openhab.core.thing.binding.ThingHandlerCallback; +import org.openhab.core.types.State; +import org.openhab.core.types.UnDefType; /** * Tests for {@link DeutscheBahnTimetableHandler}. @@ -68,11 +76,17 @@ private static Bridge mockBridge() { private DeutscheBahnTimetableHandler createAndInitHandler(final ThingHandlerCallback callback, final Bridge bridge) throws Exception { + return createAndInitHandler(callback, bridge, createApiWithTestdata().getApiFactory()); + } + + private DeutscheBahnTimetableHandler createAndInitHandler( // + final ThingHandlerCallback callback, // + final Bridge bridge, // + final TimetablesV1ApiFactory apiFactory) throws Exception { // final TimeproviderStub timeProvider = new TimeproviderStub(); timeProvider.time = new GregorianCalendar(2021, Calendar.AUGUST, 16, 9, 30); - final DeutscheBahnTimetableHandler handler = new DeutscheBahnTimetableHandler(bridge, - createApiWithTestdata().getApiFactory(), timeProvider); + final DeutscheBahnTimetableHandler handler = new DeutscheBahnTimetableHandler(bridge, apiFactory, timeProvider); handler.setCallback(callback); handler.initialize(); return handler; @@ -104,4 +118,70 @@ private void verifyThingUpdated(final Bridge bridge, int offset, String stopId) verify(childHandler, timeout(1000)) .updateChannels(argThat((TimetableStop stop) -> stop.getId().equals(stopId))); } + + @Test + public void testUpdateTrainsToUndefinedIfNoDataWasProvided() throws Exception { + final Bridge bridge = mockBridge(); + final ThingHandlerCallback callback = mock(ThingHandlerCallback.class); + + final TimetablesV1ApiStub stubWithError = TimetablesV1ApiStub.createWithException(); + + final DeutscheBahnTimetableHandler handler = createAndInitHandler(callback, bridge, + (String authToken, HttpCallable httpCallable) -> stubWithError); + + try { + verify(callback).statusUpdated(eq(bridge), argThat(arg -> arg.getStatus().equals(ThingStatus.UNKNOWN))); + verify(callback, timeout(1000)).statusUpdated(eq(bridge), + argThat(arg -> arg.getStatus().equals(ThingStatus.OFFLINE))); + + verifyChannelsUpdatedToUndef(bridge, 0, callback, UnDefType.UNDEF); + verifyChannelsUpdatedToUndef(bridge, 1, callback, UnDefType.UNDEF); + verifyChannelsUpdatedToUndef(bridge, 2, callback, UnDefType.UNDEF); + + } finally { + handler.dispose(); + } + } + + private static void verifyChannelsUpdatedToUndef(Bridge bridge, int offset, ThingHandlerCallback callback, + State expectedState) { + final Thing thing = bridge.getThings().get(offset); + for (Channel channel : thing.getChannels()) { + verify(callback).stateUpdated(eq(channel.getUID()), eq(expectedState)); + } + } + + @Test + public void testUpdateTrainsToUndefinedIfNotEnoughDataWasProvided() throws Exception { + final Bridge bridge = mockBridge(); + final ThingHandlerCallback callback = mock(ThingHandlerCallback.class); + + // Bridge contains 3 trains, but Timetable contains only 1 items, so two trains has to be updated to undef + // value. + final Timetable timetable = new Timetable(); + TimetableStop stop01 = new TimetableStop(); + stop01.setId("stop01id"); + Event dp = new Event(); + dp.setPt("2108161000"); + stop01.setDp(dp); + timetable.getS().add(stop01); + + final TimetablesV1ApiStub stubWithData = TimetablesV1ApiStub.createWithResult(timetable); + + final DeutscheBahnTimetableHandler handler = createAndInitHandler(callback, bridge, + (String authToken, HttpCallable httpCallable) -> stubWithData); + + try { + verify(callback).statusUpdated(eq(bridge), argThat(arg -> arg.getStatus().equals(ThingStatus.UNKNOWN))); + verify(callback, timeout(1000)).statusUpdated(eq(bridge), + argThat(arg -> arg.getStatus().equals(ThingStatus.ONLINE))); + + verifyThingUpdated(bridge, 0, stop01.getId()); + verifyChannelsUpdatedToUndef(bridge, 1, callback, UnDefType.UNDEF); + verifyChannelsUpdatedToUndef(bridge, 2, callback, UnDefType.UNDEF); + + } finally { + handler.dispose(); + } + } } diff --git a/bundles/org.openhab.binding.deutschebahn/src/test/java/org/openhab/binding/deutschebahn/internal/DeutscheBahnTrainHandlerTest.java b/bundles/org.openhab.binding.deutschebahn/src/test/java/org/openhab/binding/deutschebahn/internal/DeutscheBahnTrainHandlerTest.java index b619d12b17325..627e53d3f5f3d 100644 --- a/bundles/org.openhab.binding.deutschebahn/src/test/java/org/openhab/binding/deutschebahn/internal/DeutscheBahnTrainHandlerTest.java +++ b/bundles/org.openhab.binding.deutschebahn/src/test/java/org/openhab/binding/deutschebahn/internal/DeutscheBahnTrainHandlerTest.java @@ -79,6 +79,11 @@ static Thing mockThing(int id) { .thenReturn(Arrays.asList(arrivalPlannedTime, arrivalLine, arrivalChangedTime)); when(thing.getChannelsOfGroup("departure")) .thenReturn(Arrays.asList(departurePlannedTime, departurePlannedPlatform, departureTargetStation)); + when(thing.getChannels()).thenReturn(Arrays.asList( // + tripLabelCategory, // + arrivalPlannedTime, arrivalLine, arrivalChangedTime, // + departurePlannedTime, departurePlannedPlatform, departureTargetStation)); + return thing; } diff --git a/bundles/org.openhab.binding.deutschebahn/src/test/java/org/openhab/binding/deutschebahn/internal/timetable/TimetablesV1ApiStub.java b/bundles/org.openhab.binding.deutschebahn/src/test/java/org/openhab/binding/deutschebahn/internal/timetable/TimetablesV1ApiStub.java new file mode 100644 index 0000000000000..3b14cdfdc5824 --- /dev/null +++ b/bundles/org.openhab.binding.deutschebahn/src/test/java/org/openhab/binding/deutschebahn/internal/timetable/TimetablesV1ApiStub.java @@ -0,0 +1,71 @@ +/** + * Copyright (c) 2010-2021 Contributors to the openHAB project + * + * See the NOTICE file(s) distributed with this work for additional + * information. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0 + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.openhab.binding.deutschebahn.internal.timetable; + +import java.io.IOException; +import java.util.Date; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; +import org.openhab.binding.deutschebahn.internal.timetable.dto.Timetable; + +/** + * Stub Implementation of {@link TimetablesV1Api}, that may return an preconfigured Timetable or + * throws an {@link IOException} if not data has been set. + * + * @author Sönke Küper - initial contribution + */ +@NonNullByDefault +public final class TimetablesV1ApiStub implements TimetablesV1Api { + + @Nullable + private final Timetable result; + + private TimetablesV1ApiStub(@Nullable Timetable result) { + this.result = result; + } + + /** + * Creates an new {@link TimetablesV1ApiStub}, that returns the given result. + */ + public static TimetablesV1ApiStub createWithResult(Timetable timetable) { + return new TimetablesV1ApiStub(timetable); + } + + /** + * Creates an new {@link TimetablesV1ApiStub} that throws an Exception. + */ + public static TimetablesV1ApiStub createWithException() { + return new TimetablesV1ApiStub(null); + } + + @Override + public Timetable getPlan(String evaNo, Date time) throws IOException { + final Timetable currentResult = this.result; + if (currentResult == null) { + throw new IOException("No timetable data is available"); + } else { + return currentResult; + } + } + + @Override + public Timetable getFullChanges(String evaNo) throws IOException { + return new Timetable(); + } + + @Override + public Timetable getRecentChanges(String evaNo) throws IOException { + return new Timetable(); + } +} diff --git a/bundles/org.openhab.binding.deutschebahn/src/test/resources/timetablesData/plan/8000152/211014/11.xml b/bundles/org.openhab.binding.deutschebahn/src/test/resources/timetablesData/plan/8000152/211014/11.xml index 2be9ae5017514..52bb29f7e56dd 100644 --- a/bundles/org.openhab.binding.deutschebahn/src/test/resources/timetablesData/plan/8000152/211014/11.xml +++ b/bundles/org.openhab.binding.deutschebahn/src/test/resources/timetablesData/plan/8000152/211014/11.xml @@ -1 +1,282 @@ - \ No newline at end of file + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file