/* * Copyright 2014 michael-simons.eu. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package ac.simons.bikingFX.api; import java.net.MalformedURLException; import java.net.URL; import java.util.Collection; import java.util.logging.Level; import java.util.logging.Logger; import java.util.stream.Collectors; import javafx.collections.FXCollections; import javafx.collections.ObservableList; import javafx.concurrent.Task; import javax.json.Json; import javax.json.JsonReader; import javax.json.JsonValue; /** * Retrieves JSON from a given API endpoint and converts it to Java Objects * using the given {@link ObjectFactory}. * <br> * Be aware that no error checking (http etc.) whatsoever is done here. * * @author Michael J. Simons, 2014-10-18 */ public class JsonRetrievalTask<T> extends Task<Collection<T>> { public static final String HOST_AND_PORT = "https://biking.michael-simons.eu"; public static final String BASE_URL = HOST_AND_PORT + "/api"; private static final Logger logger = Logger.getLogger(JsonRetrievalTask.class.getName()); @FunctionalInterface public interface ObjectFactory<T> { T createObject(final JsonValue jsonValue); } /** * Instantiates a new retrieval task, sets up an observable list, starts the task in a * separate thread and fills the list on succeeded state. * * @param <T> * @param objectFactory * @param endpoint * @return */ public static <T> ObservableList<T> get(final ObjectFactory<T> objectFactory, final String endpoint) { final ObservableList<T> rv = FXCollections.observableArrayList(); final JsonRetrievalTask<T> bikesRetrievalTask = new JsonRetrievalTask<>(objectFactory, endpoint); bikesRetrievalTask.setOnSucceeded(state -> { rv.addAll((Collection<T>) state.getSource().getValue()); }); new Thread(bikesRetrievalTask).start(); return rv; } private final URL apiEndpoint; private final ObjectFactory<T> objectFactory; protected JsonRetrievalTask(final ObjectFactory<T> objectFactory, final String endpoint) { URL hlp = null; try { hlp = new URL(String.format("%s%s", BASE_URL, endpoint)); } catch (MalformedURLException e) { // I hope so ;) throw new RuntimeException(e); } this.apiEndpoint = hlp; this.objectFactory = objectFactory; } @Override protected Collection<T> call() throws Exception { logger.log(Level.FINE, "Retrieving list of objects from {0}", new Object[]{this.apiEndpoint.toString()}); try (final JsonReader jsonReader = Json.createReader(apiEndpoint.openStream())) { logger.log(Level.FINE, "Done."); return jsonReader.readArray().stream().map(objectFactory::createObject).collect(Collectors.toList()); } } }