/**
* Copyright (C) 2011 Brian Ferris <bdferris@onebusaway.org>
*
* 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 org.onebusaway.transit_data_federation.bundle.tasks.transfer_pattern.utilities;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.GnuParser;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.apache.commons.cli.Parser;
import org.onebusaway.csv_entities.CSVLibrary;
import org.onebusaway.utility.IOLibrary;
public class TransferPatternUtilityMain {
private static final String ARG_HUB_STOPS = "hubStops";
private static final String ARG_PRUNE_DIRECT_TRANSFERS = "pruneDirectTransfers";
public static void main(String[] args) throws Exception {
TransferPatternUtilityMain m = new TransferPatternUtilityMain();
m.run(args);
}
private long _currentIndex = 0;
private Map<String, String> _idMapping = new HashMap<String, String>();
public void run(String[] args) throws ParseException, IOException {
Options options = createOptions();
Parser parser = new GnuParser();
CommandLine cli = parser.parse(options, args);
args = cli.getArgs();
if (args.length == 0) {
usage();
System.exit(-1);
}
boolean pruneDirectTransfers = cli.hasOption(ARG_PRUNE_DIRECT_TRANSFERS);
Map<String, Integer> hubStops = loadHubStops(cli);
Set<String> originStopsWeHaveSeen = new HashSet<String>();
Set<String> pruneFromParent = new HashSet<String>();
Map<String, Integer> depths = new HashMap<String, Integer>();
Map<String, String> directTransfers = new HashMap<String, String>();
for (String arg : args) {
System.err.println("# " + arg);
BufferedReader reader = new BufferedReader(IOLibrary.getPathAsReader(arg));
String line = null;
int originHubDepth = Integer.MAX_VALUE;
String originIndex = null;
boolean skipTree = false;
while ((line = reader.readLine()) != null) {
if (line.length() == 0)
continue;
List<String> tokens = new CSVLibrary().parse(line);
String index = tokens.get(0);
String stopId = tokens.get(1);
String type = tokens.get(2);
String parentIndex = null;
if (tokens.size() > 3)
parentIndex = tokens.get(3);
int depth = 0;
boolean isOrigin = false;
if (parentIndex == null) {
isOrigin = true;
originHubDepth = hubDepth(hubStops, stopId);
_idMapping.clear();
pruneFromParent.clear();
depths.clear();
directTransfers.clear();
depths.put(index, 0);
skipTree = false;
if (originStopsWeHaveSeen.add(stopId)) {
System.err.println("# Origin Stop: " + stopId);
} else {
System.err.println("# Skipping duplicate origin stop: " + stopId);
skipTree = true;
}
}
if (skipTree)
continue;
if (parentIndex != null) {
if (pruneFromParent.contains(parentIndex)) {
pruneFromParent.add(index);
continue;
}
/**
* If we had an uncommited parent, commit it
*/
String parentStopId = directTransfers.remove(parentIndex);
if (parentStopId != null)
commitLine(parentIndex, parentStopId, "0", originIndex);
depth = depths.get(parentIndex) + 1;
depths.put(index, depth);
String newParentIndex = _idMapping.get(parentIndex);
tokens.set(3, newParentIndex);
parentIndex = newParentIndex;
}
int hubDepth = hubDepth(hubStops, stopId);
if ((depth % 2) == 0 && hubDepth < originHubDepth) {
pruneFromParent.add(index);
type = "2";
}
if (pruneDirectTransfers && depth == 1) {
directTransfers.put(index, stopId);
} else {
String newIndex = commitLine(index, stopId, type, parentIndex);
if (isOrigin)
originIndex = newIndex;
}
}
reader.close();
}
}
private String commitLine(String index, String stopId, String type,
String parentIndex) {
String newIndex = Long.toString(_currentIndex);
_idMapping.put(index, newIndex);
String newLine = parentIndex == null ? CSVLibrary.getAsCSV(newIndex,
stopId, type)
: CSVLibrary.getAsCSV(newIndex, stopId, type, parentIndex);
System.out.println(newLine);
_currentIndex++;
return newIndex;
}
private int hubDepth(Map<String, Integer> hubStops, String stopId) {
int hubDepth = Integer.MAX_VALUE;
if (hubStops.containsKey(stopId))
hubDepth = hubStops.get(stopId);
return hubDepth;
}
private Options createOptions() {
Options options = new Options();
options.addOption(ARG_HUB_STOPS, true, "");
options.addOption(ARG_PRUNE_DIRECT_TRANSFERS, false, "");
return options;
}
private void usage() {
System.err.println("usage: [-hubStops HubStops.txt] [-pruneDirectTransfers] trace [trace ...]");
}
private Map<String, Integer> loadHubStops(CommandLine cli) throws IOException {
if (!cli.hasOption(ARG_HUB_STOPS))
return Collections.emptyMap();
Map<String, Integer> hubStops = new HashMap<String, Integer>();
BufferedReader reader = new BufferedReader(new FileReader(
cli.getOptionValue(ARG_HUB_STOPS)));
String line = null;
while ((line = reader.readLine()) != null) {
List<String> tokens = new CSVLibrary().parse(line);
String stopId = tokens.get(0);
int depth = 0;
if (tokens.size() > 1)
depth = Integer.parseInt(tokens.get(1));
if (!hubStops.containsKey(stopId))
hubStops.put(stopId, depth);
}
reader.close();
return hubStops;
}
}