/**
* H2GIS is a library that brings spatial support to the H2 Database Engine
* <http://www.h2database.com>. H2GIS is developed by CNRS
* <http://www.cnrs.fr/>.
*
* This code is part of the H2GIS project. H2GIS 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;
* version 3.0 of the License.
*
* H2GIS 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 Lesser General Public License
* for more details <http://www.gnu.org/licenses/>.
*
*
* For more information, please consult: <http://www.h2gis.org/>
* or contact directly: info_at_h2gis.org
*/
package org.h2gis.network.functions;
/**
* A helper class for parsing String arguments to h2network graph functions.
*
* @author Adam Gouge
*/
public class GraphFunctionParser {
private String weightColumn;
private Orientation globalOrientation;
private String edgeOrientation;
public static final String SEPARATOR = "-";
public static final String DIRECTED = "directed";
public static final String REVERSED = "reversed";
public static final String UNDIRECTED = "undirected";
public enum Orientation {
DIRECTED, REVERSED, UNDIRECTED
}
public static final String EDGE_ORIENTATION_COLUMN = "edge_orientation_column";
public static final String POSSIBLE_ORIENTATIONS =
"'" + DIRECTED + " - " + EDGE_ORIENTATION_COLUMN + "' "
+ "| '" + REVERSED + " - " + EDGE_ORIENTATION_COLUMN + "' "
+ "| '" + UNDIRECTED + "'";
public static final String ORIENTATION_ERROR =
"Bad orientation format. Enter " + POSSIBLE_ORIENTATIONS + ".";
/**
* Recovers the weight column name from a string.
*
* @param v String
*
* @return the weight column name
*/
protected String parseWeight(String v) {
if (v == null) {
return null;
}
return v.trim();
}
/**
* Recovers the global orientation from a string.
*
*
* @param v String
* @return The global orientation
*/
protected static Orientation parseGlobalOrientation(String v) {
if (v == null) {
return null;
}
if (isDirectedString(v)) {
return Orientation.DIRECTED;
} else if (isReversedString(v)) {
return Orientation.REVERSED;
} else if (isUndirectedString(v)) {
return Orientation.UNDIRECTED;
} else {
throw new IllegalArgumentException(ORIENTATION_ERROR);
}
}
private static boolean isDirectedString(String s) {
if (s == null) {
return false;
}
return s.toLowerCase().contains(DIRECTED)
&& !isUndirectedString(s);
}
private static boolean isReversedString(String s) {
if (s == null) {
return false;
}
return s.toLowerCase().contains(REVERSED);
}
private static boolean isUndirectedString(String s) {
if (s == null) {
return false;
}
return s.toLowerCase().contains(UNDIRECTED);
}
private boolean isOrientationString(String s) {
return isDirectedString(s) || isReversedString(s) || isUndirectedString(s);
}
private boolean isWeightString(String s) {
if (s == null) {
return false;
}
return !isOrientationString(s);
}
/**
* Recovers the edge orientation from a string.
*
* @param v String
* @return The edge orientation
*/
protected String parseEdgeOrientation(String v) {
if (v == null) {
return null;
}
if (!v.contains(SEPARATOR)) {
throw new IllegalArgumentException(ORIENTATION_ERROR);
}
// Extract the global and edge orientations.
String[] s = v.split(SEPARATOR);
if (s.length == 2) {
// Return just the edge orientation column name and not the
// global orientation.
return s[1].trim();
} else {
throw new IllegalArgumentException(ORIENTATION_ERROR);
}
}
/**
* Parse the weight and orientation(s) from two strings, given in arbitrary
* order.
*
* @param arg1 Weight or orientation
* @param arg2 Weight or orientation
*/
public void parseWeightAndOrientation(String arg1, String arg2) {
if ((arg1 == null && arg2 == null)
|| (isWeightString(arg1) && arg2 == null)
|| (arg1 == null && isWeightString(arg2))) {
// Disable default orientations (D and WD).
throw new IllegalArgumentException("You must specify the orientation.");
}
if (isWeightString(arg1) && isWeightString(arg2)) {
throw new IllegalArgumentException("Cannot specify the weight column twice.");
}
if (isOrientationString(arg1) && isOrientationString(arg2)) {
throw new IllegalArgumentException("Cannot specify the orientation twice.");
}
if (isWeightString(arg1) || isOrientationString(arg2)) {
setWeightAndOrientation(arg1, arg2);
}
if (isOrientationString(arg1) || isWeightString(arg2)) {
setWeightAndOrientation(arg2, arg1);
}
}
private void setWeightAndOrientation(String weight, String orient) {
weightColumn = parseWeight(weight);
globalOrientation = parseGlobalOrientation(orient);
if (globalOrientation != null) {
if (!globalOrientation.equals(Orientation.UNDIRECTED)) {
edgeOrientation = parseEdgeOrientation(orient);
}
}
}
/**
* Get the weight column name.
*
* @return weight column name
*/
public String getWeightColumn() {
return weightColumn;
}
/**
* Get the global orientation string.
*
* @return global orientation string
*/
public Orientation getGlobalOrientation() {
return globalOrientation;
}
/**
* Get the edge orientation column name.
*
* @return edge orientation column name
*/
public String getEdgeOrientation() {
return edgeOrientation;
}
/**
* Returns true if the given string contains a comma.
* @param s String
* @return true if the given string contains a comma
*/
protected static boolean isDestinationsString(String s) {
return s.substring(0, 1).matches("[0-9]");
}
/**
* Returns an array of destination ids from a comma-separated list of
* destinations.
*
* @param s Comma-separated list of destinations
*
* @return An array of destination ids
*/
public static int[] parseDestinationsString(String s) {
if (!s.contains(",")) {
return new int[]{Integer.valueOf(s.trim())};
}
String[] array = s.split(",");
int[] destinations = new int[array.length];
for (int i = 0; i < destinations.length; i++) {
final String stringWithNoWhiteSpaces = array[i].replaceAll("\\s", "");
if (stringWithNoWhiteSpaces.isEmpty()) {
throw new IllegalArgumentException("Empty destination. Too many commas?");
}
destinations[i] = Integer.valueOf(stringWithNoWhiteSpaces);
}
return destinations;
}
}