/**
   * Before downloading a file for map icons (see "retrieveMapImageForIcon" below), first remove any
   * existing .img and .img.* files
   *
   * <p>e.g. delete all that start with (DataFile name) + ".img"
   *
   * @param mapLayerMetadata
   * @return
   * @throws IOException
   */
  private boolean deleteOlderMapThumbnails(MapLayerMetadata mapLayerMetadata) {
    if (mapLayerMetadata == null) {
      logger.warning("mapLayerMetadata is null");
      return false;
    }

    // Retrieve the data file
    //
    DataFile df = mapLayerMetadata.getDataFile();

    try {
      DataFileIO dataAccess = df.getAccessObject();

      if (dataAccess == null || !dataAccess.isLocalFile()) {
        return false;
      }
      // Get the parent directory
      //
      Path fileDirname = dataAccess.getFileSystemPath().getParent();
      if (fileDirname == null) {
        logger.warning(
            "DataFile directory has null path.  Directory path: "
                + dataAccess.getFileSystemPath().toString());
        return false;
      }

      // Verify that the directory exists
      //
      File fileDirectory = new File(fileDirname.normalize().toString());
      if (!(fileDirectory.isDirectory())) {
        logger.warning(
            "DataFile directory is not actuall a directory.  Directory path: "
                + fileDirectory.toString());
        return false;
      }

      /* Iterate through directory and delete any ".img" files for this DataFile

          Example:
          Datafile name: 14a5e4abf7d-e7eebfb6474d
          Types of files that would be deleted (if they exist):
              14a5e4abf7d-e7eebfb6474d.img
              14a5e4abf7d-e7eebfb6474d.img.thumb64
              14a5e4abf7d-e7eebfb6474d.img.thumb400
      */
      String iconBaseFilename = dataAccess.getFileSystemPath().toString() + ".img";

      for (File singleFile : fileDirectory.listFiles()) {
        if (singleFile.toString().startsWith(iconBaseFilename)) {
          // logger.info("file found: " + singleFile.toString());
          singleFile.delete();
          // results.add(file.getName());
        }
      }
    } catch (IOException ioEx) {
      return false;
    }

    return true;
  }
 public MapLayerMetadata save(MapLayerMetadata layer_metadata) {
   if (layer_metadata == null) {
     return null;
   }
   if (layer_metadata.getId() == null) {
     em.persist(layer_metadata);
     return layer_metadata;
   } else {
     return em.merge(layer_metadata);
   }
 }
  /*
      Delete a mapLayerMetadata object.

      First check if the given user has permission to edit this data.

  */
  public boolean deleteMapLayerMetadataObject(MapLayerMetadata mapLayerMetadata, User user) {
    logger.info("deleteMapLayerMetadataObject");

    if ((mapLayerMetadata == null) || (user == null)) {
      return false;
    }

    if (permissionService
        .userOn(user, mapLayerMetadata.getDataFile().getOwner())
        .has(Permission.EditDataset)) {
      em.remove(em.merge(mapLayerMetadata));

      this.deleteOlderMapThumbnails(mapLayerMetadata);
      return true;
    }
    return false;
  }
  /**
   * Use the mapLayerMetadata.mapImageLink to retrieve a PNG file directly from WorldMap
   *
   * <p>Next step: Save this image as the default icon
   *
   * <p>Example mapImageLink:
   * http://worldmap.harvard.edu/download/wms/14708/png?layers=geonode:power_plants_enipedia_jan_2014_kvg&width=948&bbox=76.04800165,18.31860358,132.0322222,50.78441&service=WMS&format=image/png&srs=EPSG:4326&request=GetMap&height=550
   *
   * <p>Parameter by parameter (note width/height):
   * http://worldmap.harvard.edu/download/wms/14708/png?
   * layers=geonode:power_plants_enipedia_jan_2014_kvg width=948
   * bbox=76.04800165,18.31860358,132.0322222,50.78441 service=WMS format=image/png srs=EPSG:4326
   * request=GetMap height=550
   *
   * @param mapLayerMetadata
   * @return boolean
   * @throws IOException
   */
  public boolean retrieveMapImageForIcon(MapLayerMetadata mapLayerMetadata) throws IOException {
    if (mapLayerMetadata == null) {
      logger.warning("mapLayerMetadata is null");
      return false;
    }

    this.deleteOlderMapThumbnails(mapLayerMetadata);
    if (true) {
      // debug check
      // return false;
    }
    if ((mapLayerMetadata.getMapImageLink() == null)
        || mapLayerMetadata.getMapImageLink().isEmpty()) {
      logger.warning("mapLayerMetadata does not have a 'map_image_link' attribute");
      return false;
    }

    String imageUrl = mapLayerMetadata.getMapImageLink();
    imageUrl = imageUrl.replace("https:", "http:");
    logger.info("Attempt to retrieve map image: " + imageUrl);

    DataFileIO dataAccess = null;
    try {
      dataAccess = mapLayerMetadata.getDataFile().getAccessObject();
    } catch (IOException ioEx) {
      dataAccess = null;
    }

    if (dataAccess == null || !dataAccess.isLocalFile()) {
      return false;
    }
    String destinationFile = dataAccess.getFileSystemPath().toString() + ".img";
    logger.info(
        "destinationFile: getFileSystemLocation()" + dataAccess.getFileSystemPath().toString());
    logger.info("destinationFile: " + destinationFile);

    URL url = new URL(imageUrl);
    logger.info("retrieve url : " + imageUrl);

    logger.info("try to open InputStream");
    InputStream is = null;

    try {
      is = url.openStream();
    } catch (IOException exio) {
      logger.warning("Error when retrieving map icon image. Exception: " + exio.getMessage());
      if (is != null) {
        try {
          is.close();
        } catch (IOException ignore) {
        }
      }
      return false;
    }

    OutputStream os = null;

    try {
      logger.info("try to start OutputStream");
      os = new FileOutputStream(destinationFile);
    } catch (Exception ex) {
      logger.warning("Error when retrieving map icon image. Exception: " + ex.getMessage());
      if (os != null) {
        try {
          os.close();
        } catch (IOException ignore) {
        }
      }
      return false;
    }

    byte[] b = new byte[2048];
    int length;

    logger.info("Writing file...");
    while ((length = is.read(b)) != -1) {
      os.write(b, 0, length);
    }

    logger.info("Closing streams...");
    is.close();
    os.close();

    logger.info("Done");
    return true;
  }