gt:                 obj = _globalJson.get (globalKey);
context: /*
   * Copyright (C) 2009-2017 by the geOrchestra PSC
   *
   * This file is part of geOrchestra.
   *
   * geOrchestra is free software: you can redistribute it and/or modify it under
   * the terms of the GNU General Public License as published by the Free
   * Software Foundation, either version 3 of the License, or (at your option)
   * any later version.
   *
   * geOrchestra 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
   * geOrchestra.  If not, see <http://www.gnu.org/licenses/>.
   */
  
  package org.georchestra.extractorapp.ws.extractor;
  
  import com.vividsolutions.jts.geom.Envelope;
  import org.geotools.geometry.jts.ReferencedEnvelope;
  import org.geotools.referencing.CRS;
  import org.json.JSONArray;
  import org.json.JSONException;
  import org.json.JSONObject;
  import org.json.JSONTokener;
  import org.opengis.referencing.FactoryException;
  import org.opengis.referencing.NoSuchAuthorityCodeException;
  import org.opengis.referencing.crs.CoordinateReferenceSystem;
  
  import java.io.File;
  import java.net.MalformedURLException;
  import java.net.URL;
  import java.util.ArrayList;
  import java.util.List;
  
  /**
   * Encapsulates all the parameters of an extractor request for one layer
   * 
   * @author jeichar
   */
  public class ExtractorLayerRequest {
      static final String            EMAILS_KEY           = "emails";
      static final String            LAYERS_KEY           = "layers";
      static final String            NAMESPACE_KEY        = "namespace";
      static final String            GLOBAL_PROPS_KEY     = "globalProperties";
      public static final String            URL_KEY              = "owsUrl";
      public static final String            TYPE_KEY             = "owsType";
      public static final String            LAYER_NAME_KEY       = "layerName";
      public static final String            PROJECTION_KEY       = "projection";
      public static final String            FORMAT_KEY           = "format";
      static final String            VECTOR_FORMAT_KEY    = "vectorFormat";
      static final String            RASTER_FORMAT_KEY    = "rasterFormat";
      public static final String            BBOX_KEY             = "bbox";
      public static final String            BBOX_SRS_KEY         = "srs";
      public static final String            BBOX_VALUE_KEY       = "value";
      static final String            RESOLUTION_KEY       = "resolution";
      public static final String            ISO_METADATA_URL_KEY	= "isoMetadataURL";
  
      public final String[]                  _emails;
      public final URL                       _url;
      public final CoordinateReferenceSystem _projection;
      public final OWSType                   _owsType;
      public final String                    _format;
      public final ReferencedEnvelope        _bbox;
      public final String                    _epsg;
      public final String                    _layerName;
      public final String                    _namespace;
      public final double                    _resolution;
  	public final URL                       _isoMetadataURL;
  
      private final JSONObject               _layerJson;
      private final JSONObject               _globalJson;
      private String _wfsName;
      private Long dbLogId;
  
      public ExtractorLayerRequest (JSONObject layerJson, JSONObject globalJson, JSONArray emails) throws NoSuchAuthorityCodeException,
              FactoryException, MalformedURLException, JSONException {
          _layerJson = layerJson;
          _globalJson = globalJson;
          _emails = parseEmails(emails);
          _url = parseURL ();
          _epsg = parseProjection ();
          _projection = CRS.decode (_epsg);
          _owsType = parseType ();
          _format = parseFormat ();
          _bbox = parseBbox ();
          _resolution = parseResolution ();
          _layerName = parseLayerName ();
          _namespace = parseNameSpace ();
          _isoMetadataURL = parseIsoMetadataURL();
      }
  
      /**
       * Convert the _url to a capabilities url
       * @param service the type of service to access
       * @param version the version of the ows
       */
      public URL capabilitiesURL(String service, String version) throws MalformedURLException {
  
      	String externalForm = _url.toExternalForm();
    
      	String versionParam = version == null ? "" : "&VERSION=" + version;
          
          String query = "REQUEST=GETCAPABILITIES&SERVICE=" + service + versionParam ;
          
          if (externalForm.endsWith("?")) {
              return new URL(externalForm + query);
          } else if (externalForm.contains("?")) {
              return new URL(externalForm + "&" + query);
          } else {
              return new URL(externalForm + "?" + query);
          }
      }
  
      /**
       * Create the directory to extract this layer to
       */
      public File createContainingDir(File basedir) {
          String dirname = FileUtils.toSafeFileName(_url.getHost()+"_"+_layerName);
          File dir = new File(basedir, dirname );
          
          for(int i=1; dir.exists(); i++){
              dir = new File(basedir, dirname+"_"+i);
          }
          return dir;
      }
  
  
      /** --------------- Factory methods ------------------ */
      /**
       * Create a list of requests from jsonData. One per layer requested
       * 
       * @param jsonData
       */
      public static List<ExtractorLayerRequest> parseJson (String jsonData) throws JSONException,
              NoSuchAuthorityCodeException, FactoryException, MalformedURLException {
          JSONObject jsonObject = parseStringToJSon(jsonData);
          JSONArray emails = jsonObject.getJSONArray (EMAILS_KEY);
          JSONArray jsonLayers = jsonObject.getJSONArray (LAYERS_KEY);
          JSONObject globalProps = jsonObject.getJSONObject (GLOBAL_PROPS_KEY);
  
          ArrayList<ExtractorLayerRequest> layers = new ArrayList<ExtractorLayerRequest> ();
          for (int i = 0; i < jsonLayers.length (); i++) {
              ExtractorLayerRequest layer = new ExtractorLayerRequest (jsonLayers.getJSONObject (i), globalProps, emails);
              layers.add (layer);
          }
          return layers;
      }
  
      /**
       * Takes a string and parses it to a JSON object structure
       */
      public static JSONObject parseStringToJSon(String jsonData) throws JSONException {
          final String trimmed = jsonData.trim ();
          final JSONTokener tokener = new JSONTokener (trimmed);
          JSONObject jsonObject = new JSONObject (tokener);
          return jsonObject;
      }
  
      /* --------------- Private methods ------------------ */
  
      private String[] parseEmails(JSONArray jsonEmails) throws JSONException {
          String[] emails = new String[jsonEmails.length()];
          for (int i = 0; i < emails.length; i++) {
              emails[i] = jsonEmails.getString(i);
          }
          return emails;
      }
      
      private URL parseURL () throws MalformedURLException, JSONException {
          String url = _layerJson.getString (URL_KEY);
          return new URL (url);
      }
  
      private URL parseIsoMetadataURL() throws MalformedURLException {
          
      	try{
      		String metadataURL = _layerJson.getString (ISO_METADATA_URL_KEY);
          
      		return new URL (metadataURL);
      		
      	} catch(JSONException e){
      		
      		return null;
      	}
      	
      }
      
      private String parseProjection () throws JSONException {
          String projection = get (PROJECTION_KEY, PROJECTION_KEY, false).toString ();
          return projection;
      }
  
      private Object get (String layerKey, String globalKey, boolean optional) throws JSONException {
          Object obj = _layerJson.opt (layerKey);
          if (obj == null || "null".equalsIgnoreCase (obj.toString ())) {
              if (optional) {
                  obj = _globalJson.opt (globalKey);
              } else {
  