From 07efeeb766e0c0cd9f47bcf08fe826a9b51dfb26 Mon Sep 17 00:00:00 2001 From: Andrew Byrd Date: Mon, 2 Feb 2015 20:02:25 +0100 Subject: [PATCH] Change config from Properties to JSON #1726 --- .../common/OTPConfigPreferences.java | 204 ------------------ .../impl/EmbeddedConfigGraphBuilderImpl.java | 75 ------- .../opentripplanner/routing/graph/Graph.java | 3 +- .../routing/impl/InputStreamGraphSource.java | 55 ++--- .../routing/impl/MemoryGraphSource.java | 9 +- .../standalone/OTPConfigurator.java | 23 +- .../opentripplanner/standalone/Router.java | 5 +- .../opentripplanner/updater/GraphUpdater.java | 2 +- .../updater/GraphUpdaterConfigurator.java | 139 +++++------- ...onfigurable.java => JsonConfigurable.java} | 10 +- .../updater/PollingGraphUpdater.java | 14 +- .../updater/PropertiesPreferences.java | 156 -------------- .../alerts/GtfsRealtimeAlertsUpdater.java | 12 +- .../updater/bike_park/BikeParkUpdater.java | 11 +- .../bike_park/KmlBikeParkDataSource.java | 26 +-- .../BCycleBikeRentalDataSource.java | 7 +- .../bike_rental/BikeRentalUpdater.java | 19 +- .../CityBikesBikeRentalDataSource.java | 11 +- ...a => GenericJsonBikeRentalDataSource.java} | 29 +-- .../GenericKmlBikeRentalDataSource.java | 7 +- .../GenericXmlBikeRentalDataSource.java | 12 +- .../JCDecauxBikeRentalDataSource.java | 2 +- .../updater/example/ExampleGraphUpdater.java | 7 +- .../example/ExamplePollingGraphUpdater.java | 8 +- .../GtfsRealtimeFileTripUpdateSource.java | 11 +- .../GtfsRealtimeHttpTripUpdateSource.java | 11 +- .../stoptime/PollingStoptimeUpdater.java | 30 ++- .../WebsocketGtfsRealtimeUpdater.java | 10 +- .../WFSNotePollingGraphUpdater.java | 8 +- .../common/TestConfigFile.java | 52 ----- .../decoration/TestPropertiesPreferences.java | 59 ----- .../opentripplanner/common/invalid1.config | 19 -- .../opentripplanner/common/invalid2.config | 18 -- .../opentripplanner/common/invalid3.config | 13 -- .../opentripplanner/common/invalid4.config | 11 - .../opentripplanner/common/invalid5.config | 12 -- .../opentripplanner/common/invalid6.config | 19 -- .../org/opentripplanner/common/valid1.config | 49 ----- 38 files changed, 236 insertions(+), 932 deletions(-) delete mode 100644 src/main/java/org/opentripplanner/common/OTPConfigPreferences.java delete mode 100644 src/main/java/org/opentripplanner/graph_builder/impl/EmbeddedConfigGraphBuilderImpl.java rename src/main/java/org/opentripplanner/updater/{PreferencesConfigurable.java => JsonConfigurable.java} (74%) delete mode 100644 src/main/java/org/opentripplanner/updater/PropertiesPreferences.java rename src/main/java/org/opentripplanner/updater/bike_rental/{GenericJSONBikeRentalDataSource.java => GenericJsonBikeRentalDataSource.java} (86%) delete mode 100644 src/test/java/org/opentripplanner/common/TestConfigFile.java delete mode 100644 src/test/java/org/opentripplanner/decoration/TestPropertiesPreferences.java delete mode 100644 src/test/resources/org/opentripplanner/common/invalid1.config delete mode 100644 src/test/resources/org/opentripplanner/common/invalid2.config delete mode 100644 src/test/resources/org/opentripplanner/common/invalid3.config delete mode 100644 src/test/resources/org/opentripplanner/common/invalid4.config delete mode 100644 src/test/resources/org/opentripplanner/common/invalid5.config delete mode 100644 src/test/resources/org/opentripplanner/common/invalid6.config delete mode 100644 src/test/resources/org/opentripplanner/common/valid1.config diff --git a/src/main/java/org/opentripplanner/common/OTPConfigPreferences.java b/src/main/java/org/opentripplanner/common/OTPConfigPreferences.java deleted file mode 100644 index 34174d63142..00000000000 --- a/src/main/java/org/opentripplanner/common/OTPConfigPreferences.java +++ /dev/null @@ -1,204 +0,0 @@ -package org.opentripplanner.common; - -import com.beust.jcommander.internal.Maps; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.*; -import java.util.Arrays; -import java.util.Map; -import java.util.Stack; -import java.util.prefs.AbstractPreferences; -import java.util.prefs.BackingStoreException; - -/** - * A read-only implementation of the Java Preferences API (hierarchically structured configuration information). - * The preferences are loaded from a text configuration file where every line is either a key-value pair (where the key - * is separated from the value by whitespace characters), a child node name followed by whitespace and an opening - * bracket, or a single closing bracket. For example: - * - *
- * # This is a comment line.
- * # Note that keys may not contain whitespace but values can.
- * name The OpenTripPlanner Project
- * frequency 87.65
- * size {
- *     height 12.3
- *     width  45.6
- *     depth  78.9
- * }
- * color {
- *     red   20
- *     green 20
- *     blue  40
- * }
- * 
- * - * @author abyrd - */ -public class OTPConfigPreferences extends AbstractPreferences { - - private static final Logger LOG = LoggerFactory.getLogger(OTPConfigPreferences.class); - - OTPConfigPreferences parent; - String name; - private Map entries = Maps.newHashMap(); - private Map children = Maps.newHashMap(); - - private static void parseError(String msg, String filename, int line) { - String longmsg = String.format("parse error in config file '%s' at line %d:\n %s", filename, line, msg); - LOG.error(longmsg); - } - - private OTPConfigPreferences (OTPConfigPreferences parent, String name) { - super(parent, name); - } - - public static OTPConfigPreferences fromFile (String filename) { - OTPConfigPreferences curr = new OTPConfigPreferences(null, ""); - try (BufferedReader br = new BufferedReader(new FileReader(filename))) { - Stack stack = new Stack(); - String line; - int nline = 0; - while ((line = br.readLine()) != null) { - nline++; - String[] tokens = line.trim().split("\\s+", 2); // split on one or more whitespace characters - // System.out.println(Arrays.asList(tokens)); - if (tokens.length == 0 || tokens[0].length() == 0 || tokens[0].startsWith("#")) { - continue; - } - if (tokens.length > 2) { - parseError("line must contain a key-value pair, a child name and an opening bracket, " + - "or a single closing bracket.", filename, nline); - return null; - } - String key = tokens[0].trim(); - String val = "NONE"; - if (tokens.length > 1) val = tokens[1].trim(); - if (key.equals("}")) { - if (tokens.length > 1) { - parseError("Closing bracket should appear alone on a line.", filename, nline); - return null; - } - if (stack.isEmpty()) { - parseError("Bracket mismatch (too many closing brackets).", filename, nline); - return null; - } - curr = stack.pop(); - continue; - } - if (key.endsWith("{")) { - parseError("An opening bracket should be preceded by a child name and whitespace.", filename, nline); - return null; - } - if (val.startsWith("{") && val.length() > 1) { - parseError("The opening bracket should be the last element on a line.", filename, nline); - return null; - } - if ("{".equals(val)) { - OTPConfigPreferences child = curr.children.get(key); - if (child != null) { - parseError(String.format("Multiple definitions of child '%s'.", key), filename, nline); - return null; - } - child = new OTPConfigPreferences(curr, key); - curr.children.put(key, child); - stack.push(curr); - curr = child; - } else { - if (curr.entries.get(key) != null) { - parseError(String.format("Multiple definitions of key '%s'.", key), filename, nline); - return null; - } - curr.entries.put(key, val); - } - } - if ( ! stack.isEmpty()) { - parseError("Bracket mismatch (not enough closing brackets).", filename, nline); - return null; - } - return curr; - } catch (IOException e) { - e.printStackTrace(); - return null; - } - } - - @Override - protected void putSpi(String s, String s2) { - throw new UnsupportedOperationException("read-only preferences implementation."); - } - - @Override - protected void removeSpi(String s) { - throw new UnsupportedOperationException("Read-only preferences implementation."); - } - - @Override - protected void removeNodeSpi() throws BackingStoreException { - throw new UnsupportedOperationException("Read-only preferences implementation."); - } - - @Override - protected String[] keysSpi() throws BackingStoreException { - return entries.keySet().toArray(new String[entries.keySet().size()]); - } - - @Override - protected String[] childrenNamesSpi() throws BackingStoreException { - return children.keySet().toArray(new String[children.keySet().size()]); - } - - @Override - protected String getSpi(String s) { - return entries.get(s); - } - - @Override - protected AbstractPreferences childSpi(String name) { - OTPConfigPreferences child = children.get(name); - if (child == null || child.isRemoved()) { - child = new OTPConfigPreferences(this, name); - children.put(name, child); - } - return child; - } - - @Override - protected void syncSpi() throws BackingStoreException { - // Does nothing: read-only - } - - @Override - protected void flushSpi() throws BackingStoreException { - // Does nothing: read-only - } - - @Override - public String toString() { - return toString(0); - } - - private static int INDENT_WIDTH = 2; - private String toString (int depth) { - char[] indent = new char[depth * INDENT_WIDTH]; - Arrays.fill(indent, ' '); - StringBuilder sb = new StringBuilder(); - for (Map.Entry entry : entries.entrySet()) { - sb.append(indent); - sb.append(entry.getKey()); - sb.append(" "); - sb.append(entry.getValue()); - sb.append("\n"); - } - for (Map.Entry child : children.entrySet()) { - sb.append(indent); - sb.append(child.getKey()); - sb.append(" {\n"); - sb.append(child.getValue().toString(depth + 1)); - sb.append(indent); - sb.append("}\n"); - } - return sb.toString(); - } -} diff --git a/src/main/java/org/opentripplanner/graph_builder/impl/EmbeddedConfigGraphBuilderImpl.java b/src/main/java/org/opentripplanner/graph_builder/impl/EmbeddedConfigGraphBuilderImpl.java deleted file mode 100644 index d8bbce1af90..00000000000 --- a/src/main/java/org/opentripplanner/graph_builder/impl/EmbeddedConfigGraphBuilderImpl.java +++ /dev/null @@ -1,75 +0,0 @@ -/* This program is free software: you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public License - as published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -package org.opentripplanner.graph_builder.impl; - -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Properties; - -import org.opentripplanner.graph_builder.services.GraphBuilder; -import org.opentripplanner.routing.graph.Graph; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Embed inside the graph a default configuration used when decorating the graph during load. - * - */ -public class EmbeddedConfigGraphBuilderImpl implements GraphBuilder { - - public File propertiesFile; - - private static final Logger LOG = LoggerFactory.getLogger(EmbeddedConfigGraphBuilderImpl.class); - - public void setPropertiesPath(String propertiesPath) { - propertiesFile = new File(propertiesPath); - } - - /** - * An set of ids which identifies what stages this graph builder provides (i.e. streets, - * elevation, transit) - */ - public List provides() { - return Collections.emptyList(); - } - - /** A list of ids of stages which must be provided before this stage */ - public List getPrerequisites() { - return Collections.emptyList(); - } - - @Override - public void buildGraph(Graph graph, HashMap, Object> extra) { - try { - LOG.info("Bundling config '" + propertiesFile.getPath() + "' into graph."); - Properties props = new Properties(); - props.load(new FileInputStream(propertiesFile)); - graph.embeddedPreferences = props; - } catch (IOException e) { - LOG.error("Can't load properties from '" + propertiesFile.getAbsolutePath() + "'", e); - } - } - - @Override - public void checkInputs() { - if (!propertiesFile.canRead()) { - throw new IllegalArgumentException("Configuration '" + propertiesFile.getAbsolutePath() - + "' can't be read."); - } - } -} diff --git a/src/main/java/org/opentripplanner/routing/graph/Graph.java b/src/main/java/org/opentripplanner/routing/graph/Graph.java index 55a619a2be9..c6ac00dc440 100644 --- a/src/main/java/org/opentripplanner/routing/graph/Graph.java +++ b/src/main/java/org/opentripplanner/routing/graph/Graph.java @@ -40,6 +40,7 @@ the License, or (at your option) any later version. import java.util.concurrent.ConcurrentHashMap; import java.util.prefs.Preferences; +import com.fasterxml.jackson.databind.JsonNode; import com.google.common.collect.*; import org.joda.time.DateTime; import org.onebusaway.gtfs.impl.calendar.CalendarServiceImpl; @@ -162,7 +163,7 @@ public class Graph implements Serializable { /** * Makes it possible to embed a default configuration inside a graph. */ - public Properties embeddedPreferences = null; + public JsonNode embeddedPreferences = null; /* The preferences that were used for graph building. */ public Preferences preferences = null; diff --git a/src/main/java/org/opentripplanner/routing/impl/InputStreamGraphSource.java b/src/main/java/org/opentripplanner/routing/impl/InputStreamGraphSource.java index 87082d3e1c9..e96e1facd2f 100644 --- a/src/main/java/org/opentripplanner/routing/impl/InputStreamGraphSource.java +++ b/src/main/java/org/opentripplanner/routing/impl/InputStreamGraphSource.java @@ -19,15 +19,17 @@ the License, or (props, at your option) any later version. import java.io.IOException; import java.io.InputStream; import java.io.ObjectInputStream; -import java.util.prefs.Preferences; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.MissingNode; import org.opentripplanner.routing.graph.Graph; import org.opentripplanner.routing.graph.Graph.LoadLevel; import org.opentripplanner.routing.services.GraphSource; import org.opentripplanner.routing.services.StreetVertexIndexFactory; import org.opentripplanner.standalone.Router; import org.opentripplanner.standalone.Router.LifecycleManager; -import org.opentripplanner.updater.PropertiesPreferences; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -42,7 +44,7 @@ public class InputStreamGraphSource implements GraphSource { public static final String GRAPH_FILENAME = "Graph.obj"; - public static final String CONFIG_FILENAME = "Graph.properties"; + public static final String CONFIG_FILENAME = "router-config.json"; private static final Logger LOG = LoggerFactory.getLogger(InputStreamGraphSource.class); @@ -66,7 +68,7 @@ public class InputStreamGraphSource implements GraphSource { /** * The current used input stream implementation for getting graph data source. */ - private GraphInputStream graphInputStream; + private Streams streams; // TODO Why do we need a factory? There is a single one implementation. private StreetVertexIndexFactory streetVertexIndexFactory = new DefaultStreetVertexIndexFactory(); @@ -81,7 +83,7 @@ public class InputStreamGraphSource implements GraphSource { */ public static InputStreamGraphSource newFileGraphSource(String routerId, File path, LoadLevel loadLevel) { - return new InputStreamGraphSource(routerId, loadLevel, new FileGraphInputStream(path)); + return new InputStreamGraphSource(routerId, loadLevel, new FileStreams(path)); } /** @@ -93,14 +95,14 @@ public static InputStreamGraphSource newFileGraphSource(String routerId, File pa */ public static InputStreamGraphSource newClasspathGraphSource(String routerId, File path, LoadLevel loadLevel) { - return new InputStreamGraphSource(routerId, loadLevel, new ClasspathGraphInputStream(path)); + return new InputStreamGraphSource(routerId, loadLevel, new ClasspathStreams(path)); } private InputStreamGraphSource(String routerId, LoadLevel loadLevel, - GraphInputStream graphInputStream) { + Streams streams) { this.routerId = routerId; this.loadLevel = loadLevel; - this.graphInputStream = graphInputStream; + this.streams = streams; } @Override @@ -125,7 +127,7 @@ public Router getRouter() { public boolean reload(boolean force, boolean preEvict) { /* We synchronize on 'this' to prevent multiple reloads from being called at the same time */ synchronized (this) { - long lastModified = graphInputStream.getLastModified(); + long lastModified = streams.getLastModified(); boolean doReload = force ? true : checkAutoReload(lastModified); if (!doReload) return true; @@ -214,12 +216,10 @@ public void evict() { /** * Do the actual operation of graph loading. Load configuration if present, and startup the * router with the help of the router lifecycle manager. - * - * @return */ private Router loadGraph() { final Graph newGraph; - try (InputStream is = graphInputStream.getGraphInputStream()) { + try (InputStream is = streams.getGraphInputStream()) { LOG.info("Loading graph..."); try { newGraph = Graph.load(new ObjectInputStream(is), loadLevel, @@ -236,17 +236,24 @@ private Router loadGraph() { return null; } - // Decorate the graph. Even if a config file is not present - // one could be bundled inside. - try (InputStream is = graphInputStream.getConfigInputStream()) { - Preferences config = is == null ? null : new PropertiesPreferences(is); + // Decorate the graph (TODO how are we "decorating" it?). + // Even if a config file is not present on disk one could be bundled inside. + try (InputStream is = streams.getConfigInputStream()) { + JsonNode config = MissingNode.getInstance(); + if (is != null) { + ObjectMapper mapper = new ObjectMapper(); + mapper.configure(JsonParser.Feature.ALLOW_COMMENTS, true); + mapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true); + config = mapper.readTree(is); + } Router newRouter = new Router(routerId, newGraph); if (routerLifecycleManager != null) { routerLifecycleManager.startupRouter(newRouter, config); } return newRouter; } catch (IOException e) { - LOG.error("Can't read config file", e); + LOG.error("Can't read config file."); + LOG.error(e.getMessage()); return null; } } @@ -254,8 +261,10 @@ private Router loadGraph() { /** * InputStreamGraphSource delegates to some actual implementation the fact of getting the input * stream and checking the last modification timestamp for a given routerId. + * FIXME this seems like a lot of boilerplate just to switch between FileInputStream and getResourceAsStream + * a couple of conditional blocks and a boolean field "onClasspath" might do the trick. */ - private interface GraphInputStream { + private interface Streams { public abstract InputStream getGraphInputStream() throws IOException; public abstract InputStream getConfigInputStream() throws IOException; @@ -263,11 +272,11 @@ private interface GraphInputStream { public abstract long getLastModified(); } - private static class FileGraphInputStream implements GraphInputStream { + private static class FileStreams implements Streams { private File path; - private FileGraphInputStream(File path) { + private FileStreams(File path) { this.path = path; } @@ -296,11 +305,11 @@ public long getLastModified() { } } - private static class ClasspathGraphInputStream implements GraphInputStream { + private static class ClasspathStreams implements Streams { private File path; - private ClasspathGraphInputStream(File path) { + private ClasspathStreams(File path) { this.path = path; } @@ -332,8 +341,6 @@ public long getLastModified() { /** * A GraphSource factory creating InputStreamGraphSource from file. - * - * @see FileGraphSource */ public static class FileFactory implements GraphSource.Factory { diff --git a/src/main/java/org/opentripplanner/routing/impl/MemoryGraphSource.java b/src/main/java/org/opentripplanner/routing/impl/MemoryGraphSource.java index f580e010af0..b9caf558374 100644 --- a/src/main/java/org/opentripplanner/routing/impl/MemoryGraphSource.java +++ b/src/main/java/org/opentripplanner/routing/impl/MemoryGraphSource.java @@ -16,11 +16,12 @@ the License, or (props, at your option) any later version. import java.util.Properties; import java.util.prefs.Preferences; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.MissingNode; import org.opentripplanner.routing.graph.Graph; import org.opentripplanner.routing.services.GraphSource; import org.opentripplanner.standalone.Router; import org.opentripplanner.standalone.Router.LifecycleManager; -import org.opentripplanner.updater.PropertiesPreferences; /** * An implementation of GraphSource that store a transient graph in memory. @@ -30,15 +31,15 @@ public class MemoryGraphSource implements GraphSource { private Router router; - private Preferences config; + private JsonNode config; private Router.LifecycleManager routerLifecycleManager; public MemoryGraphSource(String routerId, Graph graph) { - this(routerId, graph, new PropertiesPreferences(new Properties())); + this(routerId, graph, MissingNode.getInstance()); } - public MemoryGraphSource(String routerId, Graph graph, Preferences config) { + public MemoryGraphSource(String routerId, Graph graph, JsonNode config) { router = new Router(routerId, graph); router.graph.routerId = routerId; this.config = config; diff --git a/src/main/java/org/opentripplanner/standalone/OTPConfigurator.java b/src/main/java/org/opentripplanner/standalone/OTPConfigurator.java index 3e72347b8b8..fa3ea46c03c 100644 --- a/src/main/java/org/opentripplanner/standalone/OTPConfigurator.java +++ b/src/main/java/org/opentripplanner/standalone/OTPConfigurator.java @@ -20,6 +20,9 @@ the License, or (at your option) any later version. import java.util.zip.ZipEntry; import java.util.zip.ZipFile; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; import org.opentripplanner.analyst.request.IsoChroneSPTRendererAccSampling; import org.opentripplanner.analyst.request.Renderer; import org.opentripplanner.analyst.request.SPTCache; @@ -27,7 +30,6 @@ the License, or (at your option) any later version. import org.opentripplanner.analyst.request.TileCache; import org.opentripplanner.api.resource.PlanGenerator; import org.opentripplanner.graph_builder.GraphBuilderTask; -import org.opentripplanner.graph_builder.impl.EmbeddedConfigGraphBuilderImpl; import org.opentripplanner.graph_builder.impl.GtfsGraphBuilderImpl; import org.opentripplanner.graph_builder.impl.PruneFloatingIslands; import org.opentripplanner.graph_builder.impl.DirectTransferGenerator; @@ -55,7 +57,6 @@ the License, or (at your option) any later version. import org.opentripplanner.routing.impl.RetryingPathServiceImpl; import org.opentripplanner.routing.services.GraphService; import org.opentripplanner.updater.GraphUpdaterConfigurator; -import org.opentripplanner.updater.PropertiesPreferences; import org.opentripplanner.visualizer.GraphVisualizer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -102,8 +103,12 @@ public void makeGraphService(Graph graph) { if (graph != null && (params.inMemory || params.preFlight)) { /* Hand off graph in memory to server in a in-memory GraphSource. */ try { - FileInputStream graphConfiguration = new FileInputStream(params.graphConfigFile); - Preferences config = new PropertiesPreferences(graphConfiguration); + FileInputStream graphConfigurationStream = new FileInputStream(params.graphConfigFile); + // FIXME this repeats code in InputStreamGraphSource + ObjectMapper mapper = new ObjectMapper(); + mapper.configure(JsonParser.Feature.ALLOW_COMMENTS, true); + mapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true); + JsonNode config = mapper.readTree(graphConfigurationStream); this.graphService.registerGraph("", new MemoryGraphSource("", graph, config)); } catch (Exception e) { if (params.graphConfigFile != null) @@ -227,11 +232,6 @@ public GraphBuilderTask builderFromParameters() { } gtfsBuilder.setFareServiceFactory(new DefaultFareServiceFactory()); } - if (configFile != null) { - EmbeddedConfigGraphBuilderImpl embeddedConfigBuilder = new EmbeddedConfigGraphBuilderImpl(); - embeddedConfigBuilder.propertiesFile = configFile; - graphBuilder.addGraphBuilder(embeddedConfigBuilder); - } if (params.elevation) { File cacheDirectory = new File(params.cacheDirectory, "ned"); ElevationGridCoverageFactory gcf = new NEDGridCoverageFactoryImpl(cacheDirectory); @@ -280,7 +280,7 @@ public GraphVisualizer visualizerFromParameters() { * analyst for some routers only). */ @Override - public void startupRouter(Router router, Preferences config) { + public void startupRouter(Router router, JsonNode config) { router.sptServiceFactory = new GenericAStarFactory(); // Choose a PathService to wrap the SPTService, depending on expected maximum path lengths @@ -313,6 +313,7 @@ public void startupRouter(Router router, Preferences config) { // Setup graph from config (Graph.properties for example) graphConfigurator.setupGraph(router.graph, config); + } @Override @@ -340,7 +341,7 @@ public static InputFileType forFile(File file) { if (name.endsWith(".osm")) return OSM; if (name.endsWith(".osm.xml")) return OSM; if (name.endsWith(".tif")) return DEM; - if (name.equals("Embed.properties")) return CONFIG; + if (name.equals(InputStreamGraphSource.CONFIG_FILENAME)) return CONFIG; return OTHER; } } diff --git a/src/main/java/org/opentripplanner/standalone/Router.java b/src/main/java/org/opentripplanner/standalone/Router.java index 3ecff37dc40..090f4dde070 100644 --- a/src/main/java/org/opentripplanner/standalone/Router.java +++ b/src/main/java/org/opentripplanner/standalone/Router.java @@ -2,6 +2,7 @@ import java.util.prefs.Preferences; +import com.fasterxml.jackson.databind.JsonNode; import org.opentripplanner.analyst.request.IsoChroneSPTRenderer; import org.opentripplanner.analyst.request.Renderer; import org.opentripplanner.analyst.request.SPTCache; @@ -26,7 +27,7 @@ public class Router { * command-line or properties file, etc...) and 2) starting / stopping real-time updaters * (delegated to the GraphUpdaterConfigurator class). * - * @see GraphUpdaterConfigurator + * @see org.opentripplanner.updater.GraphUpdaterConfigurator */ public interface LifecycleManager { @@ -35,7 +36,7 @@ public interface LifecycleManager { * @param router The router to bind/setup * @param config The configuration (loaded from Graph.properties for example). */ - public void startupRouter(Router router, Preferences config); + public void startupRouter(Router router, JsonNode config); /** * Shutdown a router when evicted / (auto-)reloaded. Stop any real-time updaters threads. diff --git a/src/main/java/org/opentripplanner/updater/GraphUpdater.java b/src/main/java/org/opentripplanner/updater/GraphUpdater.java index 7780d08ed0f..680a27d47f4 100644 --- a/src/main/java/org/opentripplanner/updater/GraphUpdater.java +++ b/src/main/java/org/opentripplanner/updater/GraphUpdater.java @@ -28,7 +28,7 @@ the License, or (at your option) any later version. * @see GraphUpdaterManager.execute * @see GraphUpdaterConfigurator */ -public interface GraphUpdater extends PreferencesConfigurable { +public interface GraphUpdater extends JsonConfigurable { /** * Graph updaters must be aware of their manager to be able to execute GraphWriterRunnables. diff --git a/src/main/java/org/opentripplanner/updater/GraphUpdaterConfigurator.java b/src/main/java/org/opentripplanner/updater/GraphUpdaterConfigurator.java index bccfd8f3323..3f88839cda3 100644 --- a/src/main/java/org/opentripplanner/updater/GraphUpdaterConfigurator.java +++ b/src/main/java/org/opentripplanner/updater/GraphUpdaterConfigurator.java @@ -21,9 +21,8 @@ the License, or (at your option) any later version. import java.util.prefs.BackingStoreException; import java.util.prefs.Preferences; +import com.fasterxml.jackson.databind.JsonNode; import org.opentripplanner.routing.graph.Graph; -import org.opentripplanner.updater.GraphUpdater; -import org.opentripplanner.updater.GraphUpdaterManager; import org.opentripplanner.updater.alerts.GtfsRealtimeAlertsUpdater; import org.opentripplanner.updater.bike_park.BikeParkUpdater; import org.opentripplanner.updater.bike_rental.BikeRentalUpdater; @@ -58,21 +57,19 @@ public class GraphUpdaterConfigurator { private static Logger LOG = LoggerFactory.getLogger(GraphUpdaterConfigurator.class); - public void setupGraph(Graph graph, Preferences mainConfig) { + public void setupGraph(Graph graph, JsonNode mainConfig) { // Create a updater manager for this graph GraphUpdaterManager updaterManager = new GraphUpdaterManager(graph); // Look for embedded config if it exists - Properties embeddedGraphPreferences = graph.embeddedPreferences; - Preferences embeddedConfig = null; - if (embeddedGraphPreferences != null) { - embeddedConfig = new PropertiesPreferences(embeddedGraphPreferences); - } + // TODO figure out how we will use embedded config in absence of main config. + JsonNode embeddedConfig = graph.embeddedPreferences; LOG.info("Using configurations: " + (mainConfig == null ? "" : "[main]") + " " + (embeddedConfig == null ? "" : "[embedded]")); - // Apply configuration - updaterManager = applyConfigurationToGraph(graph, updaterManager, Arrays.asList(mainConfig, embeddedConfig)); + // Apply configuration + // FIXME why are we returning the same updatermanager object that has been modified ? this method could just create it. + updaterManager = applyConfigurationToGraph(graph, updaterManager, mainConfig); // Stop the updater manager if it contains nothing if (updaterManager.size() == 0) { @@ -85,85 +82,63 @@ public void setupGraph(Graph graph, Preferences mainConfig) { } /** - * Apply a list of configs to a graph. Please note that the order of the config in the list *is - * important* as a child node already seen will not be overriden. * @param graph * @param updaterManager is the graph updater manager to which all updaters should be added - * @param configs is the list of configs. - * @return reference to the same updaterManager as was given as input + * @return reference to the same updaterManager as was given as input */ - private GraphUpdaterManager applyConfigurationToGraph(Graph graph, GraphUpdaterManager updaterManager, List configs) { - try { - Set configurableNames = new HashSet(); - for (Preferences config : configs) { - if (config == null) { - // This config is not used; skip it - continue; + private GraphUpdaterManager applyConfigurationToGraph(Graph graph, GraphUpdaterManager updaterManager, JsonNode config) { + for (JsonNode configItem : config) { + + // For each sub-node, determine which kind of updater is being created. + String type = configItem.path("type").asText(); + GraphUpdater updater = null; + if (type != null) { + if (type.equals("bike-rental")) { + updater = new BikeRentalUpdater(); } - for (String configurableName : config.childrenNames()) { - if (configurableNames.contains(configurableName)) { - // Already processed this configurable; skip it - continue; - } - configurableNames.add(configurableName); - - // Determine the updater - Preferences prefs = config.node(configurableName); - String type = prefs.get("type", null); - GraphUpdater updater = null; - if (type != null) { - if (type.equals("bike-rental")) { - updater = new BikeRentalUpdater(); - } - else if (type.equals("bike-park")) { - updater = new BikeParkUpdater(); - } - else if (type.equals("stop-time-updater")) { - updater = new PollingStoptimeUpdater(); - } - else if (type.equals("websocket-gtfs-rt-updater")) { - updater = new WebsocketGtfsRealtimeUpdater(); - } - else if (type.equals("real-time-alerts")) { - updater = new GtfsRealtimeAlertsUpdater(); - } - else if (type.equals("example-updater")) { - updater = new ExampleGraphUpdater(); - } - else if (type.equals("example-polling-updater")) { - updater = new ExamplePollingGraphUpdater(); - } - else if (type.equals("winkki-polling-updater")) { - updater = new WinkkiPollingGraphUpdater(); - } - } - - // Configure and activate the updaters - try { - // Check whether no updater type was found - if (updater == null) { - LOG.error("Unknown updater type: " + type); - } - else { - // Add manager as parent - updater.setGraphUpdaterManager(updaterManager); - - // Configure updater if found and necessary - if (updater instanceof PreferencesConfigurable) { - ((PreferencesConfigurable) updater).configure(graph, prefs); - } - - // Add graph updater to manager - updaterManager.addUpdater(updater); - } - } catch (Exception e) { - LOG.error("Can't configure: " + configurableName, e); - // Continue on next configurable + else if (type.equals("bike-park")) { + updater = new BikeParkUpdater(); + } + else if (type.equals("stop-time-updater")) { + updater = new PollingStoptimeUpdater(); + } + else if (type.equals("websocket-gtfs-rt-updater")) { + updater = new WebsocketGtfsRealtimeUpdater(); + } + else if (type.equals("real-time-alerts")) { + updater = new GtfsRealtimeAlertsUpdater(); + } + else if (type.equals("example-updater")) { + updater = new ExampleGraphUpdater(); + } + else if (type.equals("example-polling-updater")) { + updater = new ExamplePollingGraphUpdater(); + } + else if (type.equals("winkki-polling-updater")) { + updater = new WinkkiPollingGraphUpdater(); + } + } + + // Configure and activate the new updater. + try { + // Check whether no updater type was found + if (updater == null) { + LOG.error("Unknown updater type: " + type); + } else { + // Add manager as parent + updater.setGraphUpdaterManager(updaterManager); + // Configure updater if found and necessary + if (updater instanceof JsonConfigurable) { + ((JsonConfigurable) updater).configure(graph, configItem); } + // Add graph updater to manager + updaterManager.addUpdater(updater); + LOG.info ("Configured GraphUpdater: {}", updater); } + } catch (Exception e) { + LOG.error("Can't configure: " + configItem.asText(), e); + // Continue on to the next node } - } catch (BackingStoreException e) { - LOG.error("Can't read configuration", e); // Should not happen } return updaterManager; } diff --git a/src/main/java/org/opentripplanner/updater/PreferencesConfigurable.java b/src/main/java/org/opentripplanner/updater/JsonConfigurable.java similarity index 74% rename from src/main/java/org/opentripplanner/updater/PreferencesConfigurable.java rename to src/main/java/org/opentripplanner/updater/JsonConfigurable.java index f379044e91c..1ef204f6b7d 100644 --- a/src/main/java/org/opentripplanner/updater/PreferencesConfigurable.java +++ b/src/main/java/org/opentripplanner/updater/JsonConfigurable.java @@ -15,14 +15,14 @@ the License, or (at your option) any later version. import java.util.prefs.Preferences; +import com.fasterxml.jackson.databind.JsonNode; import org.opentripplanner.routing.graph.Graph; /** - * Interface for a class than can be configured through Preferences (the new API which kind of - * replaces Properties). - * + * Interface for a class than can be configured through a Jackson JSON tree. */ -public interface PreferencesConfigurable { +public interface JsonConfigurable { + + public abstract void configure (Graph graph, JsonNode jsonNode) throws Exception; - public abstract void configure(Graph graph, Preferences preferences) throws Exception; } diff --git a/src/main/java/org/opentripplanner/updater/PollingGraphUpdater.java b/src/main/java/org/opentripplanner/updater/PollingGraphUpdater.java index e93ec4eb0d4..8fe9afbcfbc 100644 --- a/src/main/java/org/opentripplanner/updater/PollingGraphUpdater.java +++ b/src/main/java/org/opentripplanner/updater/PollingGraphUpdater.java @@ -13,6 +13,7 @@ the License, or (at your option) any later version. package org.opentripplanner.updater; +import com.fasterxml.jackson.databind.JsonNode; import org.opentripplanner.routing.graph.Graph; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -46,7 +47,7 @@ public abstract class PollingGraphUpdater implements GraphUpdater { /** * Mirrors GraphUpdater.configure method. */ - abstract protected void configurePolling(Graph graph, Preferences preferences) throws Exception; + abstract protected void configurePolling(Graph graph, JsonNode config) throws Exception; /** * The number of seconds between two polls @@ -86,12 +87,13 @@ final public void run() { } } + /** Shared configuration code for all polling graph updaters. */ @Override - final public void configure(Graph graph, Preferences preferences) throws Exception { + final public void configure (Graph graph, JsonNode config) throws Exception { // Configure polling system - frequencySec = preferences.getInt("frequencySec", 60); - type = preferences.get("type", ""); - // Configure concrete class - configurePolling(graph, preferences); + frequencySec = config.path("frequencySec").asInt(60); + type = config.path("type").asText(""); + // Additional configuration for the concrete subclass + configurePolling(graph, config); } } diff --git a/src/main/java/org/opentripplanner/updater/PropertiesPreferences.java b/src/main/java/org/opentripplanner/updater/PropertiesPreferences.java deleted file mode 100644 index c6bc366a5e3..00000000000 --- a/src/main/java/org/opentripplanner/updater/PropertiesPreferences.java +++ /dev/null @@ -1,156 +0,0 @@ -/* This program is free software: you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public License - as published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -package org.opentripplanner.updater; - -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.Enumeration; -import java.util.HashSet; -import java.util.Map; -import java.util.Properties; -import java.util.Set; -import java.util.TreeMap; -import java.util.prefs.AbstractPreferences; -import java.util.prefs.BackingStoreException; -import java.util.prefs.Preferences; - -/** - * A read-only and .properties-file backed implementation of standard Java "Preferences". - * - * The generated Preference will have nodes based on the dotted-path of properties, like path and - * filenames. - * - */ -public class PropertiesPreferences extends AbstractPreferences { - - private Map root; - - private Map children; - - public PropertiesPreferences(File file) throws IOException { - this(new FileInputStream(file)); - } - - public PropertiesPreferences(InputStream inputStream) throws IOException { - super(null, ""); - root = new TreeMap(); - children = new TreeMap(); - Properties properties = new Properties(); - properties.load(inputStream); - initFromProperties(properties); - } - - public PropertiesPreferences(Properties properties) { - super(null, ""); - root = new TreeMap(); - children = new TreeMap(); - initFromProperties(properties); - } - - private PropertiesPreferences(AbstractPreferences parent, String name, Properties properties) { - super(parent, name); - root = new TreeMap(); - children = new TreeMap(); - initFromProperties(properties); - } - - private void initFromProperties(Properties properties) { - if (properties == null) - return; - String path = getDottedPath(); - final Enumeration pnen = properties.propertyNames(); - Set childrenNodes = new HashSet(); - while (pnen.hasMoreElements()) { - String key = (String) pnen.nextElement(); - if (key.startsWith(path)) { - String subKey = key.substring(path.length()); - int dotIndex = subKey.indexOf('.'); - if (dotIndex == -1) { - root.put(subKey, properties.getProperty(key)); - } else { - String childName = subKey.substring(0, dotIndex); - childrenNodes.add(childName); - } - } - } - for (String childName : childrenNodes) { - children.put(childName, new PropertiesPreferences(this, childName, properties)); - } - } - - private String getDottedPath() { - Preferences cursor = this; - StringBuffer retval = new StringBuffer(); - while (cursor != null) { - if (cursor.name().length() > 0) - retval.insert(0, cursor.name() + "."); - cursor = cursor.parent(); - } - return retval.toString(); - } - - @Override - protected void putSpi(String key, String value) { - throw new UnsupportedOperationException( - "Read-only implementation of preferences: putSpi() not supported."); - } - - @Override - protected String getSpi(String key) { - return root.get(key); - } - - @Override - protected void removeSpi(String key) { - throw new UnsupportedOperationException( - "Read-only implementation of preferences: removeSpi() not supported."); - } - - @Override - protected void removeNodeSpi() throws BackingStoreException { - throw new UnsupportedOperationException( - "Read-only implementation of preferences: removeNodeSpi() not supported."); - } - - @Override - protected String[] keysSpi() throws BackingStoreException { - return root.keySet().toArray(new String[root.keySet().size()]); - } - - @Override - protected String[] childrenNamesSpi() throws BackingStoreException { - return children.keySet().toArray(new String[children.keySet().size()]); - } - - @Override - protected PropertiesPreferences childSpi(String name) { - PropertiesPreferences child = children.get(name); - if (child == null || child.isRemoved()) { - child = new PropertiesPreferences(this, name, null); - children.put(name, child); - } - return child; - } - - @Override - protected void syncSpi() throws BackingStoreException { - // Does nothing: read-only - } - - protected void flushSpi() throws BackingStoreException { - // Does nothing: read-only - } -} diff --git a/src/main/java/org/opentripplanner/updater/alerts/GtfsRealtimeAlertsUpdater.java b/src/main/java/org/opentripplanner/updater/alerts/GtfsRealtimeAlertsUpdater.java index 4347f9c932a..d4df699d668 100644 --- a/src/main/java/org/opentripplanner/updater/alerts/GtfsRealtimeAlertsUpdater.java +++ b/src/main/java/org/opentripplanner/updater/alerts/GtfsRealtimeAlertsUpdater.java @@ -16,6 +16,7 @@ the License, or (at your option) any later version. import java.io.InputStream; import java.util.prefs.Preferences; +import com.fasterxml.jackson.databind.JsonNode; import org.opentripplanner.routing.graph.Graph; import org.opentripplanner.routing.impl.AlertPatchServiceImpl; import org.opentripplanner.routing.services.AlertPatchService; @@ -64,19 +65,18 @@ public void setGraphUpdaterManager(GraphUpdaterManager updaterManager) { } @Override - protected void configurePolling(Graph graph, Preferences preferences) throws Exception { + protected void configurePolling(Graph graph, JsonNode config) throws Exception { // TODO: add options to choose different patch services AlertPatchService alertPatchService = new AlertPatchServiceImpl(graph); this.alertPatchService = alertPatchService; - String url = preferences.get("url", null); + String url = config.path("url").asText(); if (url == null) { throw new IllegalArgumentException("Missing mandatory 'url' parameter"); } this.url = url; - this.earlyStart = preferences.getInt("earlyStartSec", 0); - this.defaultAgencyId = preferences.get("defaultAgencyId", null); - LOG.info("Creating real-time alert updater running every {} seconds : {}", - frequencySec, url); + this.earlyStart = config.path("earlyStartSec").asInt(0); + this.defaultAgencyId = config.path("defaultAgencyId").asText(); + LOG.info("Creating real-time alert updater running every {} seconds : {}", frequencySec, url); } @Override diff --git a/src/main/java/org/opentripplanner/updater/bike_park/BikeParkUpdater.java b/src/main/java/org/opentripplanner/updater/bike_park/BikeParkUpdater.java index 46d33474499..c2e179c082f 100644 --- a/src/main/java/org/opentripplanner/updater/bike_park/BikeParkUpdater.java +++ b/src/main/java/org/opentripplanner/updater/bike_park/BikeParkUpdater.java @@ -24,6 +24,7 @@ the License, or (at your option) any later version. import java.util.concurrent.ExecutionException; import java.util.prefs.Preferences; +import com.fasterxml.jackson.databind.JsonNode; import org.opentripplanner.routing.bike_park.BikePark; import org.opentripplanner.routing.bike_rental.BikeRentalStationService; import org.opentripplanner.routing.edgetype.BikeParkEdge; @@ -33,7 +34,7 @@ the License, or (at your option) any later version. import org.opentripplanner.updater.GraphUpdaterManager; import org.opentripplanner.updater.GraphWriterRunnable; import org.opentripplanner.updater.PollingGraphUpdater; -import org.opentripplanner.updater.PreferencesConfigurable; +import org.opentripplanner.updater.JsonConfigurable; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -80,9 +81,9 @@ public void setGraphUpdaterManager(GraphUpdaterManager updaterManager) { } @Override - protected void configurePolling(Graph graph, Preferences preferences) throws Exception { + protected void configurePolling(Graph graph, JsonNode config) throws Exception { // Set source from preferences - String sourceType = preferences.get("sourceType", null); + String sourceType = config.path("sourceType").asText(); BikeParkDataSource source = null; if (sourceType != null) { if (sourceType.equals("kml-placemarks")) { @@ -92,8 +93,8 @@ protected void configurePolling(Graph graph, Preferences preferences) throws Exc if (source == null) { throw new IllegalArgumentException("Unknown bike rental source type: " + sourceType); - } else if (source instanceof PreferencesConfigurable) { - ((PreferencesConfigurable) source).configure(graph, preferences); + } else if (source instanceof JsonConfigurable) { + ((JsonConfigurable) source).configure(graph, config); } // Configure updater diff --git a/src/main/java/org/opentripplanner/updater/bike_park/KmlBikeParkDataSource.java b/src/main/java/org/opentripplanner/updater/bike_park/KmlBikeParkDataSource.java index 3ffd1d6c85f..c83621f5a0f 100644 --- a/src/main/java/org/opentripplanner/updater/bike_park/KmlBikeParkDataSource.java +++ b/src/main/java/org/opentripplanner/updater/bike_park/KmlBikeParkDataSource.java @@ -18,9 +18,10 @@ the License, or (at your option) any later version. import java.util.Map; import java.util.prefs.Preferences; +import com.fasterxml.jackson.databind.JsonNode; import org.opentripplanner.routing.bike_park.BikePark; import org.opentripplanner.routing.graph.Graph; -import org.opentripplanner.updater.PreferencesConfigurable; +import org.opentripplanner.updater.JsonConfigurable; import org.opentripplanner.util.xml.XmlDataListDownloader; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -35,7 +36,7 @@ the License, or (at your option) any later version. * @author laurent * @author GoAbout */ -public class KmlBikeParkDataSource implements BikeParkDataSource, PreferencesConfigurable { +public class KmlBikeParkDataSource implements BikeParkDataSource, JsonConfigurable { private static final Logger LOG = LoggerFactory.getLogger(KmlBikeParkDataSource.class); @@ -77,14 +78,6 @@ public BikePark build(Map attributes) { }); } - public void setUrl(String url) { - this.url = url; - } - - public void setNamePrefix(String namePrefix) { - this.namePrefix = namePrefix; - } - /** * Update the data from the source; * @@ -114,11 +107,14 @@ public String toString() { } @Override - public void configure(Graph graph, Preferences preferences) { - String url = preferences.get("url", null); - if (url == null) + public void configure (Graph graph, JsonNode config) { + String url = config.path("url").asText(); + if (url == null) { throw new IllegalArgumentException("Missing mandatory 'url' configuration."); - setUrl(url); - setNamePrefix(preferences.get("namePrefix", null)); + } + this.url = url; + this.namePrefix = config.path("namePrefix").asText(); } + + public void setUrl (String url) {this.url = url;} } diff --git a/src/main/java/org/opentripplanner/updater/bike_rental/BCycleBikeRentalDataSource.java b/src/main/java/org/opentripplanner/updater/bike_rental/BCycleBikeRentalDataSource.java index 937def704aa..3619061a688 100644 --- a/src/main/java/org/opentripplanner/updater/bike_rental/BCycleBikeRentalDataSource.java +++ b/src/main/java/org/opentripplanner/updater/bike_rental/BCycleBikeRentalDataSource.java @@ -21,10 +21,11 @@ the License, or (at your option) any later version. /** * Build a BikeRentalStation object from a B-Cycle data source JsonNode object. * - * @see GenericJSONBikeRentalDataSource + * @see GenericJsonBikeRentalDataSource */ -public class BCycleBikeRentalDataSource extends GenericJSONBikeRentalDataSource { - public BCycleBikeRentalDataSource(String apiKey) { +public class BCycleBikeRentalDataSource extends GenericJsonBikeRentalDataSource { + + public BCycleBikeRentalDataSource(String apiKey) { super("", apiKey); } diff --git a/src/main/java/org/opentripplanner/updater/bike_rental/BikeRentalUpdater.java b/src/main/java/org/opentripplanner/updater/bike_rental/BikeRentalUpdater.java index ce772a9a168..a4a5053dab1 100644 --- a/src/main/java/org/opentripplanner/updater/bike_rental/BikeRentalUpdater.java +++ b/src/main/java/org/opentripplanner/updater/bike_rental/BikeRentalUpdater.java @@ -25,19 +25,19 @@ the License, or (at your option) any later version. import java.util.concurrent.ExecutionException; import java.util.prefs.Preferences; +import com.fasterxml.jackson.databind.JsonNode; import org.opentripplanner.routing.bike_rental.BikeRentalStation; import org.opentripplanner.routing.bike_rental.BikeRentalStationService; import org.opentripplanner.routing.edgetype.RentABikeOffEdge; import org.opentripplanner.routing.edgetype.RentABikeOnEdge; import org.opentripplanner.routing.edgetype.loader.LinkRequest; import org.opentripplanner.routing.edgetype.loader.NetworkLinkerLibrary; -import org.opentripplanner.routing.graph.Edge; import org.opentripplanner.routing.graph.Graph; import org.opentripplanner.routing.vertextype.BikeRentalStationVertex; import org.opentripplanner.updater.GraphUpdaterManager; import org.opentripplanner.updater.GraphWriterRunnable; import org.opentripplanner.updater.PollingGraphUpdater; -import org.opentripplanner.updater.PreferencesConfigurable; +import org.opentripplanner.updater.JsonConfigurable; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -80,10 +80,11 @@ public void setGraphUpdaterManager(GraphUpdaterManager updaterManager) { } @Override - protected void configurePolling(Graph graph, Preferences preferences) throws Exception { - // Set source from preferences - String sourceType = preferences.get("sourceType", null); - String apiKey = preferences.get("apiKey", null); + protected void configurePolling (Graph graph, JsonNode config) throws Exception { + + // Set data source type from config JSON + String sourceType =config.path("sourceType").asText(); + String apiKey =config.path("apiKey").asText(); BikeRentalDataSource source = null; if (sourceType != null) { if (sourceType.equals("jcdecaux")) { @@ -105,15 +106,15 @@ protected void configurePolling(Graph graph, Preferences preferences) throws Exc if (source == null) { throw new IllegalArgumentException("Unknown bike rental source type: " + sourceType); - } else if (source instanceof PreferencesConfigurable) { - ((PreferencesConfigurable) source).configure(graph, preferences); + } else if (source instanceof JsonConfigurable) { + ((JsonConfigurable) source).configure(graph, config); } // Configure updater LOG.info("Setting up bike rental updater."); this.graph = graph; this.source = source; - this.network = preferences.get("networks", DEFAULT_NETWORK_LIST); + this.network = config.path("networks").asText(DEFAULT_NETWORK_LIST); LOG.info("Creating bike-rental updater running every {} seconds : {}", frequencySec, source); } diff --git a/src/main/java/org/opentripplanner/updater/bike_rental/CityBikesBikeRentalDataSource.java b/src/main/java/org/opentripplanner/updater/bike_rental/CityBikesBikeRentalDataSource.java index 768ca2cf573..e9aad03b7b8 100644 --- a/src/main/java/org/opentripplanner/updater/bike_rental/CityBikesBikeRentalDataSource.java +++ b/src/main/java/org/opentripplanner/updater/bike_rental/CityBikesBikeRentalDataSource.java @@ -28,7 +28,7 @@ the License, or (at your option) any later version. import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; -import org.opentripplanner.updater.PreferencesConfigurable; +import org.opentripplanner.updater.JsonConfigurable; import org.opentripplanner.routing.bike_rental.BikeRentalStation; import org.opentripplanner.routing.graph.Graph; import org.opentripplanner.util.HttpUtils; @@ -37,7 +37,7 @@ the License, or (at your option) any later version. import org.xml.sax.SAXException; // TODO This class could probably inherit from GenericJSONBikeRentalDataSource -public class CityBikesBikeRentalDataSource implements BikeRentalDataSource, PreferencesConfigurable { +public class CityBikesBikeRentalDataSource implements BikeRentalDataSource, JsonConfigurable { private static final Logger log = LoggerFactory.getLogger(BixiBikeRentalDataSource.class); @@ -125,10 +125,11 @@ public String toString() { } @Override - public void configure(Graph graph, Preferences preferences) { - String url = preferences.get("url", null); - if (url == null) + public void configure(Graph graph, JsonNode config) { + String url = config.path("url").asText(); + if (url == null) { throw new IllegalArgumentException("Missing mandatory 'url' configuration."); + } setUrl(url); } diff --git a/src/main/java/org/opentripplanner/updater/bike_rental/GenericJSONBikeRentalDataSource.java b/src/main/java/org/opentripplanner/updater/bike_rental/GenericJsonBikeRentalDataSource.java similarity index 86% rename from src/main/java/org/opentripplanner/updater/bike_rental/GenericJSONBikeRentalDataSource.java rename to src/main/java/org/opentripplanner/updater/bike_rental/GenericJsonBikeRentalDataSource.java index 4e0ac03fb98..0db467fe724 100644 --- a/src/main/java/org/opentripplanner/updater/bike_rental/GenericJSONBikeRentalDataSource.java +++ b/src/main/java/org/opentripplanner/updater/bike_rental/GenericJsonBikeRentalDataSource.java @@ -6,7 +6,7 @@ import java.util.List; import java.util.prefs.Preferences; -import org.opentripplanner.updater.PreferencesConfigurable; +import org.opentripplanner.updater.JsonConfigurable; import org.opentripplanner.routing.bike_rental.BikeRentalStation; import org.opentripplanner.routing.graph.Graph; import org.opentripplanner.util.HttpUtils; @@ -23,9 +23,9 @@ * * @see BikeRentalDataSource */ -public abstract class GenericJSONBikeRentalDataSource implements BikeRentalDataSource, PreferencesConfigurable { +public abstract class GenericJsonBikeRentalDataSource implements BikeRentalDataSource, JsonConfigurable { - private static final Logger log = LoggerFactory.getLogger(GenericJSONBikeRentalDataSource.class); + private static final Logger log = LoggerFactory.getLogger(GenericJsonBikeRentalDataSource.class); private String url; private String apiKey; @@ -40,7 +40,7 @@ public abstract class GenericJSONBikeRentalDataSource implements BikeRentalDataS * Separate path levels with '/' For example "d/list" * */ - public GenericJSONBikeRentalDataSource(String jsonPath) { + public GenericJsonBikeRentalDataSource(String jsonPath) { jsonParsePath = jsonPath; apiKey= null; } @@ -53,7 +53,7 @@ public GenericJSONBikeRentalDataSource(String jsonPath) { * @param Api key, when used by bike rental type * */ - public GenericJSONBikeRentalDataSource(String jsonPath, String apiKeyValue) { + public GenericJsonBikeRentalDataSource(String jsonPath, String apiKeyValue) { jsonParsePath = jsonPath; apiKey = apiKeyValue; } @@ -63,7 +63,7 @@ public GenericJSONBikeRentalDataSource(String jsonPath, String apiKeyValue) { * Construct superclass where rental list is on the top level of JSON code * */ - public GenericJSONBikeRentalDataSource() { + public GenericJsonBikeRentalDataSource() { jsonParsePath = ""; } @@ -153,10 +153,6 @@ public String getUrl() { return url; } - public void setUrl(String url) { - this.url = url; - } - public abstract BikeRentalStation makeStation(JsonNode rentalStationNode); @Override @@ -164,11 +160,16 @@ public String toString() { return getClass().getName() + "(" + url + ")"; } + /** + * Note that the JSON being passed in here is for configuration of the OTP component, it's completely separate + * from the JSON coming in from the update source. + */ @Override - public void configure(Graph graph, Preferences preferences) { - String url = preferences.get("url", null); - if (url == null) + public void configure (Graph graph, JsonNode jsonNode) { + String url = jsonNode.path("url").asText(); // path() returns MissingNode not null. + if (url == null) { throw new IllegalArgumentException("Missing mandatory 'url' configuration."); - setUrl(url); + } + this.url = url; } } diff --git a/src/main/java/org/opentripplanner/updater/bike_rental/GenericKmlBikeRentalDataSource.java b/src/main/java/org/opentripplanner/updater/bike_rental/GenericKmlBikeRentalDataSource.java index 5ce45a75349..e3db565bcba 100644 --- a/src/main/java/org/opentripplanner/updater/bike_rental/GenericKmlBikeRentalDataSource.java +++ b/src/main/java/org/opentripplanner/updater/bike_rental/GenericKmlBikeRentalDataSource.java @@ -20,6 +20,7 @@ the License, or (at your option) any later version. import java.util.Set; import java.util.prefs.Preferences; +import com.fasterxml.jackson.databind.JsonNode; import org.opentripplanner.routing.bike_rental.BikeRentalStation; import org.opentripplanner.routing.graph.Graph; import org.slf4j.Logger; @@ -96,9 +97,9 @@ public BikeRentalStation makeStation(Map attributes) { } @Override - public void configure(Graph graph, Preferences preferences) { - super.configure(graph, preferences); - setNamePrefix(preferences.get("namePrefix", null)); + public void configure(Graph graph, JsonNode config) { + super.configure(graph, config); + setNamePrefix(config.path("namePrefix").asText()); } } diff --git a/src/main/java/org/opentripplanner/updater/bike_rental/GenericXmlBikeRentalDataSource.java b/src/main/java/org/opentripplanner/updater/bike_rental/GenericXmlBikeRentalDataSource.java index 031e7a6010f..52a820029f0 100644 --- a/src/main/java/org/opentripplanner/updater/bike_rental/GenericXmlBikeRentalDataSource.java +++ b/src/main/java/org/opentripplanner/updater/bike_rental/GenericXmlBikeRentalDataSource.java @@ -18,14 +18,15 @@ the License, or (at your option) any later version. import java.util.Map; import java.util.prefs.Preferences; +import com.fasterxml.jackson.databind.JsonNode; import org.opentripplanner.routing.bike_rental.BikeRentalStation; import org.opentripplanner.routing.graph.Graph; -import org.opentripplanner.updater.PreferencesConfigurable; +import org.opentripplanner.updater.JsonConfigurable; import org.opentripplanner.util.xml.XmlDataListDownloader; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public abstract class GenericXmlBikeRentalDataSource implements BikeRentalDataSource, PreferencesConfigurable { +public abstract class GenericXmlBikeRentalDataSource implements BikeRentalDataSource, JsonConfigurable { private static final Logger LOG = LoggerFactory.getLogger(GenericXmlBikeRentalDataSource.class); @@ -79,10 +80,11 @@ public String toString() { } @Override - public void configure(Graph graph, Preferences preferences) { - String url = preferences.get("url", null); - if (url == null) + public void configure(Graph graph, JsonNode config) { + String url = config.path("url").asText(); + if (url == null) { throw new IllegalArgumentException("Missing mandatory 'url' configuration."); + } setUrl(url); } } diff --git a/src/main/java/org/opentripplanner/updater/bike_rental/JCDecauxBikeRentalDataSource.java b/src/main/java/org/opentripplanner/updater/bike_rental/JCDecauxBikeRentalDataSource.java index a968002348e..95b7f963d2e 100644 --- a/src/main/java/org/opentripplanner/updater/bike_rental/JCDecauxBikeRentalDataSource.java +++ b/src/main/java/org/opentripplanner/updater/bike_rental/JCDecauxBikeRentalDataSource.java @@ -23,7 +23,7 @@ the License, or (at your option) any later version. * @link https://developer.jcdecaux.com * @see BikeRentalDataSource */ -public class JCDecauxBikeRentalDataSource extends GenericJSONBikeRentalDataSource { +public class JCDecauxBikeRentalDataSource extends GenericJsonBikeRentalDataSource { public JCDecauxBikeRentalDataSource() { super(""); diff --git a/src/main/java/org/opentripplanner/updater/example/ExampleGraphUpdater.java b/src/main/java/org/opentripplanner/updater/example/ExampleGraphUpdater.java index 98ad52c21ec..0553a08bac7 100644 --- a/src/main/java/org/opentripplanner/updater/example/ExampleGraphUpdater.java +++ b/src/main/java/org/opentripplanner/updater/example/ExampleGraphUpdater.java @@ -16,6 +16,7 @@ the License, or (at your option) any later version. import java.util.concurrent.ExecutionException; import java.util.prefs.Preferences; +import com.fasterxml.jackson.databind.JsonNode; import org.opentripplanner.routing.graph.Graph; import org.opentripplanner.updater.GraphUpdater; import org.opentripplanner.updater.GraphUpdaterManager; @@ -55,9 +56,9 @@ public class ExampleGraphUpdater implements GraphUpdater { // Here the updater can be configured using the properties in the file 'Graph.properties'. @Override - public void configure(Graph graph, Preferences preferences) throws Exception { - frequencySec = preferences.getInt("frequencySec", 5); - url = preferences.get("url", null); + public void configure(Graph graph, JsonNode config) throws Exception { + frequencySec = config.path("frequencySec").asInt(5); + url = config.path("url").asText(); LOG.info("Configured example updater: frequencySec={} and url={}", frequencySec, url); } diff --git a/src/main/java/org/opentripplanner/updater/example/ExamplePollingGraphUpdater.java b/src/main/java/org/opentripplanner/updater/example/ExamplePollingGraphUpdater.java index c24f9ea80a6..4299c521524 100644 --- a/src/main/java/org/opentripplanner/updater/example/ExamplePollingGraphUpdater.java +++ b/src/main/java/org/opentripplanner/updater/example/ExamplePollingGraphUpdater.java @@ -15,6 +15,7 @@ the License, or (at your option) any later version. import java.util.prefs.Preferences; +import com.fasterxml.jackson.databind.JsonNode; import org.opentripplanner.routing.graph.Graph; import org.opentripplanner.updater.GraphUpdaterManager; import org.opentripplanner.updater.GraphWriterRunnable; @@ -53,10 +54,9 @@ public class ExamplePollingGraphUpdater extends PollingGraphUpdater { // Here the updater can be configured using the properties in the file 'Graph.properties'. // The property frequencySec is already read and used by the abstract base class. @Override - protected void configurePolling(Graph graph, Preferences preferences) throws Exception { - url = preferences.get("url", null); - LOG.info("Configured example polling updater: frequencySec={} and url={}", - frequencySec, url); + protected void configurePolling(Graph graph, JsonNode config) throws Exception { + url = config.path("url").asText(); + LOG.info("Configured example polling updater: frequencySec={} and url={}", frequencySec, url); } // Here the updater gets to know its parent manager to execute GraphWriterRunnables. diff --git a/src/main/java/org/opentripplanner/updater/stoptime/GtfsRealtimeFileTripUpdateSource.java b/src/main/java/org/opentripplanner/updater/stoptime/GtfsRealtimeFileTripUpdateSource.java index 11783175235..b1af582db21 100644 --- a/src/main/java/org/opentripplanner/updater/stoptime/GtfsRealtimeFileTripUpdateSource.java +++ b/src/main/java/org/opentripplanner/updater/stoptime/GtfsRealtimeFileTripUpdateSource.java @@ -20,8 +20,9 @@ the License, or (at your option) any later version. import java.util.List; import java.util.prefs.Preferences; +import com.fasterxml.jackson.databind.JsonNode; import org.opentripplanner.routing.graph.Graph; -import org.opentripplanner.updater.PreferencesConfigurable; +import org.opentripplanner.updater.JsonConfigurable; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -30,7 +31,7 @@ the License, or (at your option) any later version. import com.google.transit.realtime.GtfsRealtime.TripUpdate; /** Reads the GTFS-RT from a local file. */ -public class GtfsRealtimeFileTripUpdateSource implements TripUpdateSource, PreferencesConfigurable { +public class GtfsRealtimeFileTripUpdateSource implements TripUpdateSource, JsonConfigurable { private static final Logger LOG = LoggerFactory.getLogger(GtfsRealtimeFileTripUpdateSource.class); @@ -42,9 +43,9 @@ public class GtfsRealtimeFileTripUpdateSource implements TripUpdateSource, Prefe private String agencyId; @Override - public void configure(Graph graph, Preferences preferences) throws Exception { - this.agencyId = preferences.get("defaultAgencyId", null); - this.file = new File(preferences.get("file", "")); + public void configure(Graph graph, JsonNode config) throws Exception { + this.agencyId = config.path("defaultAgencyId").asText(); + this.file = new File(config.path("file").asText("")); } @Override diff --git a/src/main/java/org/opentripplanner/updater/stoptime/GtfsRealtimeHttpTripUpdateSource.java b/src/main/java/org/opentripplanner/updater/stoptime/GtfsRealtimeHttpTripUpdateSource.java index 8fce2dee346..2097189d02a 100644 --- a/src/main/java/org/opentripplanner/updater/stoptime/GtfsRealtimeHttpTripUpdateSource.java +++ b/src/main/java/org/opentripplanner/updater/stoptime/GtfsRealtimeHttpTripUpdateSource.java @@ -18,7 +18,8 @@ the License, or (at your option) any later version. import java.util.List; import java.util.prefs.Preferences; -import org.opentripplanner.updater.PreferencesConfigurable; +import com.fasterxml.jackson.databind.JsonNode; +import org.opentripplanner.updater.JsonConfigurable; import org.opentripplanner.routing.graph.Graph; import org.opentripplanner.util.HttpUtils; import org.slf4j.Logger; @@ -28,7 +29,7 @@ the License, or (at your option) any later version. import com.google.transit.realtime.GtfsRealtime.FeedMessage; import com.google.transit.realtime.GtfsRealtime.TripUpdate; -public class GtfsRealtimeHttpTripUpdateSource implements TripUpdateSource, PreferencesConfigurable { +public class GtfsRealtimeHttpTripUpdateSource implements TripUpdateSource, JsonConfigurable { private static final Logger LOG = LoggerFactory.getLogger(GtfsRealtimeHttpTripUpdateSource.class); @@ -40,13 +41,13 @@ public class GtfsRealtimeHttpTripUpdateSource implements TripUpdateSource, Prefe private String url; @Override - public void configure(Graph graph, Preferences preferences) throws Exception { - String url = preferences.get("url", null); + public void configure(Graph graph, JsonNode config) throws Exception { + String url = config.path("url").asText(); if (url == null) { throw new IllegalArgumentException("Missing mandatory 'url' parameter"); } this.url = url; - this.agencyId = preferences.get("defaultAgencyId", null); + this.agencyId = config.path("defaultAgencyId").asText(); } @Override diff --git a/src/main/java/org/opentripplanner/updater/stoptime/PollingStoptimeUpdater.java b/src/main/java/org/opentripplanner/updater/stoptime/PollingStoptimeUpdater.java index 3be06b45d1d..52a2e05f29b 100644 --- a/src/main/java/org/opentripplanner/updater/stoptime/PollingStoptimeUpdater.java +++ b/src/main/java/org/opentripplanner/updater/stoptime/PollingStoptimeUpdater.java @@ -17,12 +17,12 @@ the License, or (at your option) any later version. import java.util.concurrent.ExecutionException; import java.util.prefs.Preferences; -import org.opentripplanner.updater.PreferencesConfigurable; +import com.fasterxml.jackson.databind.JsonNode; +import org.opentripplanner.updater.JsonConfigurable; import org.opentripplanner.routing.graph.Graph; import org.opentripplanner.updater.GraphUpdaterManager; import org.opentripplanner.updater.GraphWriterRunnable; import org.opentripplanner.updater.PollingGraphUpdater; -import org.opentripplanner.updater.stoptime.TimetableSnapshotSource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -81,10 +81,10 @@ public void setGraphUpdaterManager(GraphUpdaterManager updaterManager) { } @Override - public void configurePolling(Graph graph, Preferences preferences) throws Exception { + public void configurePolling(Graph graph, JsonNode config) throws Exception { // Create update streamer from preferences - agencyId = preferences.get("defaultAgencyId", ""); - String sourceType = preferences.get("sourceType", null); + agencyId = config.path("defaultAgencyId").asText(""); + String sourceType = config.path("sourceType").asText(); if (sourceType != null) { if (sourceType.equals("gtfs-http")) { updateSource = new GtfsRealtimeHttpTripUpdateSource(); @@ -97,25 +97,21 @@ public void configurePolling(Graph graph, Preferences preferences) throws Except if (updateSource == null) { throw new IllegalArgumentException( "Unknown update streamer source type: " + sourceType); - } else if (updateSource instanceof PreferencesConfigurable) { - ((PreferencesConfigurable) updateSource).configure(graph, preferences); + } else if (updateSource instanceof JsonConfigurable) { + ((JsonConfigurable) updateSource).configure(graph, config); } - // Configure updater - int logFrequency = preferences.getInt("logFrequency", -1); + // Configure updater FIXME why are the fields objects instead of primitives? this allows null values... + int logFrequency = config.path("logFrequency").asInt(-1); if (logFrequency >= 0) { this.logFrequency = logFrequency; } - int maxSnapshotFrequency = preferences.getInt("maxSnapshotFrequencyMs", -1); - if (maxSnapshotFrequency >= 0) + int maxSnapshotFrequency = config.path("maxSnapshotFrequencyMs").asInt(-1); + if (maxSnapshotFrequency >= 0) { this.maxSnapshotFrequency = maxSnapshotFrequency; - String purgeExpiredData = preferences.get("purgeExpiredData", ""); - if (!purgeExpiredData.isEmpty()) { - this.purgeExpiredData = preferences.getBoolean("purgeExpiredData", true); } - - LOG.info("Creating stop time updater running every {} seconds : {}", - frequencySec, updateSource); + this.purgeExpiredData = config.path("purgeExpiredData").asBoolean(true); + LOG.info("Creating stop time updater running every {} seconds : {}", frequencySec, updateSource); } @Override diff --git a/src/main/java/org/opentripplanner/updater/stoptime/WebsocketGtfsRealtimeUpdater.java b/src/main/java/org/opentripplanner/updater/stoptime/WebsocketGtfsRealtimeUpdater.java index 77dd038c8ca..752d5204d16 100644 --- a/src/main/java/org/opentripplanner/updater/stoptime/WebsocketGtfsRealtimeUpdater.java +++ b/src/main/java/org/opentripplanner/updater/stoptime/WebsocketGtfsRealtimeUpdater.java @@ -18,6 +18,7 @@ the License, or (at your option) any later version. import java.util.concurrent.ExecutionException; import java.util.prefs.Preferences; +import com.fasterxml.jackson.databind.JsonNode; import org.opentripplanner.routing.graph.Graph; import org.opentripplanner.updater.GraphUpdater; import org.opentripplanner.updater.GraphUpdaterManager; @@ -86,11 +87,10 @@ public void setGraphUpdaterManager(GraphUpdaterManager updaterManager) { } @Override - public void configure(Graph graph, Preferences preferences) throws Exception { - // Read configuration - url = preferences.get("url", null); - feedId = preferences.get("feedId", ""); - reconnectPeriodSec = preferences.getInt("reconnectPeriodSec", DEFAULT_RECONNECT_PERIOD_SEC); + public void configure(Graph graph, JsonNode config) throws Exception { + url = config.path("url").asText(); + feedId = config.path("feedId").asText(""); + reconnectPeriodSec = config.path("reconnectPeriodSec").asInt(DEFAULT_RECONNECT_PERIOD_SEC); } @Override diff --git a/src/main/java/org/opentripplanner/updater/street_notes/WFSNotePollingGraphUpdater.java b/src/main/java/org/opentripplanner/updater/street_notes/WFSNotePollingGraphUpdater.java index a6d4183e79f..efafff9e9ab 100644 --- a/src/main/java/org/opentripplanner/updater/street_notes/WFSNotePollingGraphUpdater.java +++ b/src/main/java/org/opentripplanner/updater/street_notes/WFSNotePollingGraphUpdater.java @@ -1,5 +1,6 @@ package org.opentripplanner.updater.street_notes; +import com.fasterxml.jackson.databind.JsonNode; import com.google.common.collect.HashMultimap; import com.google.common.collect.SetMultimap; import com.vividsolutions.jts.geom.Geometry; @@ -81,11 +82,10 @@ public abstract class WFSNotePollingGraphUpdater extends PollingGraphUpdater { * The property frequencySec is already read and used by the abstract base class. */ @Override - protected void configurePolling(Graph graph, Preferences preferences) throws Exception { - url = new URL(preferences.get("url", null)); - featureType = preferences.get("featureType", null); + protected void configurePolling(Graph graph, JsonNode config) throws Exception { + url = new URL(config.path("url").asText()); + featureType = config.path("featureType").asText(); this.graph = graph; - LOG.info("Configured WFS polling updater: frequencySec={}, url={} and featureType={}", frequencySec, url.toString(), featureType); } diff --git a/src/test/java/org/opentripplanner/common/TestConfigFile.java b/src/test/java/org/opentripplanner/common/TestConfigFile.java deleted file mode 100644 index ba220489b3c..00000000000 --- a/src/test/java/org/opentripplanner/common/TestConfigFile.java +++ /dev/null @@ -1,52 +0,0 @@ -package org.opentripplanner.common; - -import junit.framework.TestCase; -import org.junit.Test; - -import javax.validation.constraints.AssertTrue; -import java.util.Arrays; -import java.util.prefs.Preferences; - -/** - * Created by abyrd on 10/09/14. - */ -public class TestConfigFile extends TestCase { - - private static String VALID = "src/test/resources/org/opentripplanner/common/valid1.config"; - - @Test - public void testLoadPreferences() throws Exception { - OTPConfigPreferences config = OTPConfigPreferences.fromFile(VALID); - assertNotNull(config); - // System.out.println(config.toString()); - assertTrue(config.nodeExists("/origins/filters/graphGeographicFilter")); - assertTrue (config.nodeExists("/request")); - assertFalse(config.nodeExists("/origins/filters/badFilter")); - String val; - Preferences node; - node = config.node("/origins/filters/graphGeographicFilter"); - assertTrue(node.getBoolean("stopsOnly", false)); - assertTrue(node.get("stopsOnly", "default").equals("true")); - assertTrue(node.get("nothing", "default").equals("default")); - node = config.node("batch"); - assertEquals(node.getInt("threshold", 999), 3000); - assertEquals(node.getDouble("pi", Math.PI), Math.PI); - node = config.node("origins/filters"); - assertEquals("/origins/filters", node.absolutePath()); - node = config.node("/request"); - assertTrue(Arrays.asList(node.keys()).contains("routerId")); - assertFalse(Arrays.asList(node.keys()).contains("missingThing")); - - /* Ensure that comments are being ignored */ - assertEquals(config.childrenNames().length, 4); - assertEquals(config.keys().length, 3); - - /* Test some invalid input */ - for (int i = 1; i <= 6; i++) { - String filename = String.format("src/test/resources/org/opentripplanner/common/invalid%d.config", i); - config = OTPConfigPreferences.fromFile(filename); - assertNull("For invalid input, factory method should return null.", config); - } - } - -} diff --git a/src/test/java/org/opentripplanner/decoration/TestPropertiesPreferences.java b/src/test/java/org/opentripplanner/decoration/TestPropertiesPreferences.java deleted file mode 100644 index f76b5e7de60..00000000000 --- a/src/test/java/org/opentripplanner/decoration/TestPropertiesPreferences.java +++ /dev/null @@ -1,59 +0,0 @@ -/* This program is free software: you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public License - as published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -package org.opentripplanner.decoration; - -import java.io.ByteArrayInputStream; -import java.io.InputStream; -import java.nio.charset.Charset; -import java.util.Arrays; -import java.util.prefs.Preferences; - -import org.opentripplanner.updater.PropertiesPreferences; - -import junit.framework.TestCase; - -/* - */ -public class TestPropertiesPreferences extends TestCase { - - public void testPropertiesPreference() throws Exception { - - Preferences prefs1 = new PropertiesPreferences(makeInput("pe=é\npa=1\npb=xyz\n")); - assertEquals(1, prefs1.getLong("pa", 0)); - assertEquals("xyz", prefs1.get("pb", "")); - assertEquals(-1, prefs1.getLong("pd", -1)); - assertEquals("é", prefs1.get("pe", null)); - - Preferences prefs2 = new PropertiesPreferences( - makeInput("pa=1\na.pb=2\na.b.pc=3\na.b2.pd=uvw\nb.pe=42")); - String[] children = prefs2.childrenNames(); - Arrays.sort(children); - assertEquals("a", children[0]); - assertEquals("b", children[1]); - assertEquals(1, prefs2.getLong("pa", 0)); - assertEquals(2, prefs2.node("a").getLong("pb", 0)); - assertEquals(2, prefs2.node("/a").getLong("pb", 0)); - assertEquals(3, prefs2.node("/a/b").getLong("pc", 0)); - Preferences prefs2a = prefs2.node("/a"); - assertEquals(2, prefs2a.getLong("pb", 0)); - assertEquals(-1, prefs2.node("/a/c").getLong("px", -1)); - assertEquals(null, prefs2.node("/a/c").get("py", null)); - Preferences prefs2ab2 = prefs2.node("/a/b2"); - assertEquals("uvw", prefs2ab2.get("pd", null)); - } - - private InputStream makeInput(String data) { - return new ByteArrayInputStream(data.getBytes(Charset.forName("ISO-8859-1"))); - } -} diff --git a/src/test/resources/org/opentripplanner/common/invalid1.config b/src/test/resources/org/opentripplanner/common/invalid1.config deleted file mode 100644 index c9f8f0d150e..00000000000 --- a/src/test/resources/org/opentripplanner/common/invalid1.config +++ /dev/null @@ -1,19 +0,0 @@ -# This config file is invalid since it has an extra closing bracket -numbers { - one 1 - two 2 - three 3 - four { - un 1.0 - deux 2.0 - trois 3.0 - } -} -ichi 1 -ni 2 -san 3 -# The bracket on the following line doesn't match anything -} -alpha ALPHA -beta BETA -gamma GAMMA diff --git a/src/test/resources/org/opentripplanner/common/invalid2.config b/src/test/resources/org/opentripplanner/common/invalid2.config deleted file mode 100644 index d69624f89f9..00000000000 --- a/src/test/resources/org/opentripplanner/common/invalid2.config +++ /dev/null @@ -1,18 +0,0 @@ -# This config file is invalid because it has children with no name -numbers { - one 1 - two 2 - three 3 - four { - un 1.0 - deux 2.0 - trois 3.0 - } -} - -bracketShouldBeOnSameLine -{ - alpha ALPHA - beta BETA - gamma GAMMA -} diff --git a/src/test/resources/org/opentripplanner/common/invalid3.config b/src/test/resources/org/opentripplanner/common/invalid3.config deleted file mode 100644 index 4a6cad230b8..00000000000 --- a/src/test/resources/org/opentripplanner/common/invalid3.config +++ /dev/null @@ -1,13 +0,0 @@ -# This config file is invalid since it has more opening brackets than closing ones. -numbers { - one 1 - two 2 - three 3 - four { - un 1.0 - deux 2.0 - trois 3.0 - - alpha ALPHA - beta BETA - gamma GAMMA diff --git a/src/test/resources/org/opentripplanner/common/invalid4.config b/src/test/resources/org/opentripplanner/common/invalid4.config deleted file mode 100644 index ba2033a01ea..00000000000 --- a/src/test/resources/org/opentripplanner/common/invalid4.config +++ /dev/null @@ -1,11 +0,0 @@ -# This config file is invalid because it attempts to include a key after an opening bracket on the same line - -numbers { one 1 - two 2 - three 3 - four { - un 1.0 - deux 2.0 - trois 3.0 - } -} diff --git a/src/test/resources/org/opentripplanner/common/invalid5.config b/src/test/resources/org/opentripplanner/common/invalid5.config deleted file mode 100644 index e4209fdc8bb..00000000000 --- a/src/test/resources/org/opentripplanner/common/invalid5.config +++ /dev/null @@ -1,12 +0,0 @@ -# This config file is invalid because it assigns to the same key twice -numbers { - one 1 - two 2 - three 3 - one 4 - four { - un 1.0 - deux 2.0 - trois 3.0 - } -} diff --git a/src/test/resources/org/opentripplanner/common/invalid6.config b/src/test/resources/org/opentripplanner/common/invalid6.config deleted file mode 100644 index 3c6bb1cb191..00000000000 --- a/src/test/resources/org/opentripplanner/common/invalid6.config +++ /dev/null @@ -1,19 +0,0 @@ -# This config file is invalid because it has two children with the same name -numbers { - one 1 - two 2 - three 3 - four { - quatre { - sigma SIG - delta DEL - } - un 1.0 - deux 2.0 - trois 3.0 - quatre { - one_point_one 1.1 - two_point_two 2.2 - } - } -} diff --git a/src/test/resources/org/opentripplanner/common/valid1.config b/src/test/resources/org/opentripplanner/common/valid1.config deleted file mode 100644 index 5cf1d16582e..00000000000 --- a/src/test/resources/org/opentripplanner/common/valid1.config +++ /dev/null @@ -1,49 +0,0 @@ - -# This is a test input file (and this line is a comment). - # This comment is preceded by some whitespace - -graphPath /var/otp/graphs -inputPath /home/abyrd/otpa/data -outputPath /home/abyrd/otpa/results -origins { - type csv - filename origins.csv - labelCol 1 - latCol 2 - lonCol 3 - magnitudeCol 4 - filters { - nanInfFilter - inputClampFilter - graphGeographicFilter { - stopsOnly true - #Indentation is not significant - bufferMeters 2000 - } - } -} -targets { - type shp - filename targets.shp - labelAttribute GEOID10 -} - - - #ThisCommentIsPrecededByAnEmptyLineAndWhitespaceAndIsAllOneToken - - -batch { - date 2012-07-12 - time 08:00:00 - timeZone America/New_York - threshold 3000 - mode accumulator -} -request { - routerId trimet - maxWalkDistance 2000 - clampInitialWait 1800 - arriveBy false - modes WALK,TRANSIT -} -