gt:     String status = json.getString("status");
context: /*
   * Axelor Business Solutions
   *
   * Copyright (C) 2019 Axelor (<http://axelor.com>).
   *
   * This program is free software: you can redistribute it and/or  modify
   * it under the terms of the GNU Affero General Public License, version 3,
   * as published by the Free Software Foundation.
   *
   * 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 Affero General Public License for more details.
   *
   * You should have received a copy of the GNU Affero General Public License
   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
   */
  package com.axelor.apps.base.service;
  
  import com.axelor.apps.base.db.AppBase;
  import com.axelor.apps.base.db.repo.AppBaseRepository;
  import com.axelor.apps.base.exceptions.IExceptionMessage;
  import com.axelor.apps.base.service.app.AppBaseService;
  import com.axelor.common.StringUtils;
  import com.axelor.exception.AxelorException;
  import com.axelor.exception.db.repo.TraceBackRepository;
  import com.axelor.exception.service.TraceBackService;
  import com.axelor.i18n.I18n;
  import com.google.common.base.Preconditions;
  import com.google.inject.Inject;
  import groovy.util.XmlSlurper;
  import groovy.util.slurpersupport.GPathResult;
  import groovy.util.slurpersupport.Node;
  import java.lang.invoke.MethodHandles;
  import java.math.BigDecimal;
  import java.net.URISyntaxException;
  import java.util.HashMap;
  import java.util.Iterator;
  import java.util.Map;
  import org.apache.commons.collections.CollectionUtils;
  import org.apache.commons.lang3.tuple.Pair;
  import org.apache.http.HttpStatus;
  import org.apache.http.client.utils.URIBuilder;
  import org.slf4j.Logger;
  import org.slf4j.LoggerFactory;
  import wslite.json.JSONArray;
  import wslite.json.JSONException;
  import wslite.json.JSONObject;
  import wslite.rest.ContentType;
  import wslite.rest.RESTClient;
  import wslite.rest.Response;
  
  public class MapService {
  
    @Inject protected AppBaseService appBaseService;
  
    private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
  
    private BigDecimal lat;
    private BigDecimal lon;
  
    public JSONObject geocodeGoogle(String qString) throws AxelorException, JSONException {
      if (StringUtils.isBlank(qString)) {
        return null;
      }
      // http://maps.googleapis.com/maps/api/geocode/json?address=1600+Amphitheatre+Parkway,+Mountain+View,+CA&sensor=true_or_false
  
      // TODO inject the rest client, or better, run it in the browser
      RESTClient restClient = new RESTClient("https://maps.googleapis.com");
      Map<String, Object> responseQuery = new HashMap<>();
      responseQuery.put("address", qString.trim());
      responseQuery.put("sensor", "false");
      responseQuery.put("key", getGoogleMapsApiKey());
      Map<String, Object> responseMap = new HashMap<>();
      responseMap.put("path", "/maps/api/geocode/json");
      responseMap.put("accept", ContentType.JSON);
      responseMap.put("query", responseQuery);
  
      responseMap.put("connectTimeout", 5000);
      responseMap.put("readTimeout", 10000);
      responseMap.put("followRedirects", false);
      responseMap.put("useCaches", false);
      responseMap.put("sslTrustAllCerts", true);
  
      JSONObject restResponse = getJSON(restClient.get(responseMap));
      LOG.debug("Gmap response: {}", restResponse);
  
      if (restResponse.containsKey("results")) {
        JSONArray results = (JSONArray) restResponse.get("results");
  
        if (CollectionUtils.isNotEmpty(results)) {
          JSONObject result = (JSONObject) results.iterator().next();
  
          if (result != null && result.containsKey("geometry")) {
            return (JSONObject) ((JSONObject) result.get("geometry")).get("location");
          }
        }
      }
  
      throw new AxelorException(
          appBaseService.getAppBase(),
          TraceBackRepository.CATEGORY_NO_VALUE,
          I18n.get(IExceptionMessage.MAP_RESPONSE_ERROR),
          restResponse);
  
      /*
      log.debug("restResponse = {}", restResponse)
      log.debug("restResponse.parsedResponseContent.text = {}", restResponse.parsedResponseContent.text)
       */
      // def searchresults = new JsonSlurper().parseText(restResponse.parsedResponseContent.text);
      /*
      LOG.debug("searchresults.status = {}", searchresults.status);
      if (searchresults.status == "OK") {
      	/*
      	log.debug("searchresults.results.size() = {}", searchresults.results.size())
      	log.debug("searchresults.results[0] = {}", searchresults.results[0])
      	log.debug("searchresults.results[0].address_components = {}", searchresults.results[0].address_components)
      	log.debug("searchresults.results[0].geometry.location = {}", searchresults.results[0].geometry.location)
       */
      /*
      	def results = searchresults.results;
  
      	if (results.size() > 1) {
      		response.put("multiple", true);
      	}
      	def firstPlaceFound = results[0];
  
      	if (firstPlaceFound) {
      		BigDecimal lat = new BigDecimal(firstPlaceFound.geometry.location.lat);
      		BigDecimal lng = new BigDecimal(firstPlaceFound.geometry.location.lng);
  
      		response.put("lat", lat.setScale(10, RoundingMode.HALF_EVEN));
      		response.put("lng", lng.setScale(10, RoundingMode.HALF_EVEN));
      	}
      */
      // }
    }
  
    public Map<String, Object> getMapGoogle(String qString) throws AxelorException, JSONException {
      LOG.debug("Query string: {}", qString);
      JSONObject googleResponse = geocodeGoogle(qString);
      LOG.debug("Google response: {}", googleResponse);
      if (googleResponse != null) {
        Map<String, Object> result = new HashMap<>();
        BigDecimal latitude = new BigDecimal(googleResponse.get("lat").toString());
        BigDecimal longitude = new BigDecimal(googleResponse.get("lng").toString());
        LOG.debug("URL:" + "map/gmaps.html?x=" + latitude + "&y=" + longitude + "&z=18");
        result.put(
            "url",
            "map/gmaps.html?key="
                + getGoogleMapsApiKey()
                + "&x="
                + latitude
                + "&y="
                + longitude
                + "&z=18");
        result.put("latitude", latitude);
        result.put("longitude", longitude);
        return result;
      }
  
      return null;
    }
  
    @SuppressWarnings({"rawtypes", "unchecked"})
    public Map<String, Object> getMapOsm(String qString) {
      Map<String, Object> result = new HashMap<>();
      try {
        BigDecimal latitude = BigDecimal.ZERO;
        BigDecimal longitude = BigDecimal.ZERO;
        RESTClient restClient = new RESTClient("http://nominatim.openstreetmap.org/");
        Map<String, Object> mapQuery = new HashMap<>();
        mapQuery.put("q", qString);
        mapQuery.put("format", "xml");
        mapQuery.put("polygon", true);
        mapQuery.put("addressdetails", true);
        Map<String, Object> mapHeaders = new HashMap<>();
        mapHeaders.put("HTTP referrer", "axelor");
        Map<String, Object> mapResponse = new HashMap<>();
        mapResponse.put("path", "/search");
        mapResponse.put("accept", ContentType.JSON);
        mapResponse.put("query", mapQuery);
        mapResponse.put("headers", mapHeaders);
        mapResponse.put("connectTimeout", 5000);
        mapResponse.put("readTimeout", 10000);
        mapResponse.put("followRedirects", false);
        mapResponse.put("useCaches", false);
        mapResponse.put("sslTrustAllCerts", true);
        Response restResponse = restClient.get(mapResponse);
        GPathResult searchresults = new XmlSlurper().parseText(restResponse.getContentAsString());
        Iterator<Node> iterator = searchresults.childNodes();
        if (iterator.hasNext()) {
          Node node = iterator.next();
          Map attributes = node.attributes();
          if (attributes.containsKey("lat") && attributes.containsKey("lon")) {
            if (BigDecimal.ZERO.compareTo(latitude) == 0)
              latitude = new BigDecimal(node.attributes().get("lat").toString());
            if (BigDecimal.ZERO.compareTo(longitude) == 0)
              longitude = new BigDecimal(node.attributes().get("lon").toString());
          }
        }
  
        LOG.debug("OSMap qString: {}, latitude: {}, longitude: {}", qString, latitude, longitude);
  
        if (BigDecimal.ZERO.compareTo(latitude) != 0 && BigDecimal.ZERO.compareTo(longitude) != 0) {
          result.put("url", "map/oneMarker.html?x=" + latitude + "&y=" + longitude + "&z=18");
          result.put("latitude", latitude);
          result.put("longitude", longitude);
          return result;
        }
  
      } catch (Exception e) {
        TraceBackService.trace(e);
      }
      return null;
    }
  
    public Map<String, Object> getMap(String qString) throws AxelorException, JSONException {
      LOG.debug("qString = {}", qString);
  
      switch (appBaseService.getAppBase().getMapApiSelect()) {
        case AppBaseRepository.MAP_API_GOOGLE:
          return getMapGoogle(qString);
  
        case AppBaseRepository.MAP_API_OPEN_STREET_MAP:
          return getMapOsm(qString);
  
        default:
          return null;
      }
    }
  
    public String getMapUrl(Pair<BigDecimal, BigDecimal> latLong) {
      return getMapUrl(latLong.getLeft(), latLong.getRight(), null);
    }
  
    public String getMapUrl(Pair<BigDecimal, BigDecimal> latLong, String title) {
      return getMapUrl(latLong.getLeft(), latLong.getRight(), title);
    }
  
    public String getMapUrl(BigDecimal latitude, BigDecimal longitude) {
      return getMapUrl(latitude, longitude, null);
    }
  
    public String getMapUrl(BigDecimal latitude, BigDecimal longitude, String title) {
      try {
        switch (appBaseService.getAppBase().getMapApiSelect()) {
          case AppBaseRepository.MAP_API_GOOGLE:
            final String uri = "map/gmaps.html";
            URIBuilder ub = new URIBuilder(uri);
            ub.addParameter("key", getGoogleMapsApiKey());
            ub.addParameter("x", String.valueOf(latitude));
            ub.addParameter("y", String.valueOf(longitude));
            ub.addParameter("z", String.valueOf(18));
            ub.addParameter("title", title);
            return ub.toString();
  
          case AppBaseRepository.MAP_API_OPEN_STREET_MAP:
            return "map/oneMarker.html?x=" + latitude + "&y=" + longitude + "&z=18";
  
          default:
            return null;
        }
      } catch (URISyntaxException e) {
        TraceBackService.trace(e);
        return getErrorURI(e.getMessage());
      }
    }
  
    public String getDirectionUrl(
        String key,
        Pair<BigDecimal, BigDecimal> departureLatLong,
        Pair<BigDecimal, BigDecimal> arrivalLatLong) {
      return getDirectionUrl(
          key,
          departureLatLong.getLeft(),
          departureLatLong.getRight(),
          arrivalLatLong.getLeft(),
          arrivalLatLong.getRight());
    }
  
    public String getDirectionUrl(
        String key, BigDecimal dLat, BigDecimal dLon, BigDecimal aLat, BigDecimal aLon) {
      return "map/directions.html?dx="
          + dLat
          + "&dy="
          + dLon
          + "&ax="
          + aLat
          + "&ay="
          + aLon
          + "&key="
          + key;
    }
  
    public Map<String, Object> getDirectionMapGoogle(
        String dString,
        BigDecimal dLat,
        BigDecimal dLon,
        String aString,
        BigDecimal aLat,
        BigDecimal aLon) {
      LOG.debug("departureString = {}", dString);
      LOG.debug("arrivalString = {}", aString);
      Map<String, Object> result = new HashMap<>();
      try {
        if (!checkNotNullNotZero(dLat) || !checkNotNullNotZero(dLon)) {
          getGoogleResponse(dString);
          dLat = lat;
          dLon = lon;
        }
        LOG.debug("departureLat = {}, departureLng={}", dLat, dLon);
        if (!checkNotNullNotZero(aLat) || !checkNotNullNotZero(aLon)) {
          getGoogleResponse(aString);
          aLat = lat;
          aLon = lon;
        }
        LOG.debug("arrivalLat = {}, arrivalLng={}", aLat, aLon);
  
        if (checkNotNullNotZero(dLat)
            && checkNotNullNotZero(dLon)
            && checkNotNullNotZero(aLon)
            && checkNotNullNotZero(aLat)) {
          result.put(
              "url",
              "map/directions.html?key="
                  + getGoogleMapsApiKey()
                  + "&dx="
                  + dLat
                  + "&dy="
                  + dLon
                  + "&ax="
                  + aLat
                  + "&ay="
                  + aLon);
          result.put("aLat", aLat);
          result.put("dLat", dLat);
          return result;
        }
      } catch (Exception e) {
        TraceBackService.trace(e);
      }
  
      return null;
    }
  
    protected void getGoogleResponse(String key) throws AxelorException, JSONException {
      @SuppressWarnings("unchecked")
      Map<String, Object> googleResponse = geocodeGoogle(key);
  
      lat = lon = BigDecimal.ZERO;
      if (googleResponse != null) {
        lat = new BigDecimal(googleResponse.get("lat").toString());
        lon = new BigDecimal(googleResponse.get("lng").toString());
      }
    }
  
    protected Boolean checkNotNullNotZero(BigDecimal value) {
      Boolean flag = false;
      if (value != null && BigDecimal.ZERO.compareTo(value) != 0) {
        flag = true;
      }
      return flag;
    }
  
    public void testGMapService() throws AxelorException, JSONException {
      RESTClient restClient = new RESTClient("https://maps.googleapis.com");
  
      Map<String, Object> responseQuery = new HashMap<>();
      responseQuery.put("address", "google");
      responseQuery.put("sensor", "false");
      responseQuery.put("key", getGoogleMapsApiKey());
  
      Map<String, Object> responseMap = new HashMap<>();
      responseMap.put("path", "/maps/api/geocode/json");
      responseMap.put("accept", ContentType.JSON);
      responseMap.put("query", responseQuery);
  
      responseMap.put("connectTimeout", 5000);
      responseMap.put("readTimeout", 10000);
      responseMap.put("followRedirects", false);
      responseMap.put("useCaches", false);
      responseMap.put("sslTrustAllCerts", true);
  
      Response response = restClient.get(responseMap);
      getJSON(response);
    }
  
    private JSONObject getJSON(Response response) throws AxelorException, JSONException {
      LOG.debug(
          "Gmap connection status code: {}, message: {}",
          response.getStatusCode(),
          response.getStatusMessage());
  
      AppBase appBase = appBaseService.getAppBase();
  
      if (response.getStatusCode() != HttpStatus.SC_OK) {
        String msg = String.format("%d: %s", response.getStatusCode(), response.getStatusMessage());
        throw new AxelorException(appBase, TraceBackRepository.CATEGORY_CONFIGURATION_ERROR, msg);
      }
  
      JSONObject json = new JSONObject(response.getContentAsString());
  