/src/main/java/com/atlassian/jconnect/jira/customfields/LocationParser.java
Java | 100 lines | 84 code | 11 blank | 5 comment | 14 complexity | a3ea330108c3cf8d9e17b72e8a1c5eb9 MD5 | raw file
- package com.atlassian.jconnect.jira.customfields;
- import com.atlassian.jira.util.I18nHelper;
- import com.atlassian.jira.util.MessageSet;
- import com.atlassian.jira.util.MessageSetImpl;
- import com.google.common.collect.ImmutableMap;
- import java.util.Map;
- import static java.text.MessageFormat.format;
- /**
- * Parses location string values.
- *
- */
- public final class LocationParser {
- private static final Map<String,String> DEFAULT_MESSAGES = ImmutableMap.<String,String>builder()
- .put("customfields.locationsearcher.error.nothreefields", "Raw value '{0}' should contain 3 fields separated by comma")
- .put("customfields.location.lat", "Latitude")
- .put("customfields.location.lng", "Longitude")
- .put("customfields.locationsearcher.error.parselnglat", "Unable to parse value {0} of field {1}")
- .put("customfields.locationsearcher.error.latlngnotinrange", "{0} value {1} is not in expected range {2}")
- .put("customfields.locationsearcher.error.parsedistance", "Unable to parse distance value {0}")
- .put("customfields.locationsearcher.error.distancenegative", "Distance value {0} must not be negative")
- .build();
- private LocationParser() {
- throw new AssertionError("Don't instantiate me");
- }
- public static LocationQuery validateAndParseLocationQuery(String rawValue, I18nHelper i18n, MessageSet errors) {
- final String[] split = rawValue.split(",");
- if (split.length != 3) {
- errors.addErrorMessage(i18nizeOrNot(i18n, "customfields.locationsearcher.error.nothreefields", rawValue));
- return null;
- }
- final String latName = i18nizeOrNot(i18n, "customfields.location.lat");
- final double lat = checkLatLng(i18n, errors, split[0].trim(), latName);
- if (!GeoCalculator.LAT_RANGE.containsDouble(lat)) {
- i18nizeOrNot(i18n, "customfields.locationsearcher.error.latlngnotinrange", latName, lat, GeoCalculator.LAT_RANGE);
- }
- final String lngName = i18nizeOrNot(i18n, "customfields.location.lng");
- final double lng = checkLatLng(i18n, errors, split[1].trim(), lngName);
- if (!GeoCalculator.LNG_RANGE.containsDouble(lng)) {
- i18nizeOrNot(i18n, "customfields.locationsearcher.error.latlngnotinrange", lngName, lng, GeoCalculator.LNG_RANGE);
- }
- final long distance = checkDistance(i18n, errors, split[2].trim());
- if (errors.hasAnyErrors()) {
- return null;
- }
- else return new LocationQuery(lat, lng, distance);
- }
- public static LocationQuery parseLocationQuery(String rawValue) {
- MessageSet errors = new MessageSetImpl();
- LocationQuery result = validateAndParseLocationQuery(rawValue, null, errors);
- if (errors.hasAnyErrors()) {
- throw new IllegalArgumentException("Unable to parse " + rawValue + ":\n" + errors.getErrorMessages());
- }
- return result;
- }
- private static double checkLatLng(I18nHelper i18n, MessageSet errors, String value, String name) {
- try {
- return Double.parseDouble(value);
- } catch(NumberFormatException nfe) {
- errors.addErrorMessage(i18nizeOrNot(i18n, "customfields.locationsearcher.error.parselnglat", value, name));
- }
- return -1;
- }
- private static long checkDistance(I18nHelper i18n, MessageSet errors, String value) {
- try {
- // TODO this has to be smarter if we allow users to define units
- final long distance = Long.parseLong(value);
- if (distance < 0) {
- errors.addErrorMessage(i18nizeOrNot(i18n, "customfields.locationsearcher.error.distancenegative", value));
- return -1;
- }
- return distance;
- } catch(NumberFormatException nfe) {
- errors.addErrorMessage(i18nizeOrNot(i18n, "customfields.locationsearcher.error.parsedistance", value));
- }
- return -1;
- }
- private static String i18nizeOrNot(I18nHelper i18n, String key, Object... params) {
- if (i18n != null) {
- return i18n.getText(key, params);
- } else {
- String rawMsg = DEFAULT_MESSAGES.get(key);
- if (rawMsg == null) {
- return "*** NO MESSAGE FOR <" + key + ">";
- } else {
- return format(rawMsg, params);
- }
- }
- }
- }