/**
   * _more_
   *
   * @param entry _more_
   * @param className _more_
   * @param properties _more_
   * @return _more_
   * @throws Exception _more_
   */
  private RecordFile doMakeRecordFile(Entry entry, String className, Hashtable properties)
      throws Exception {
    Class c = Misc.findClass(className);
    Constructor ctor = Misc.findConstructor(c, new Class[] {String.class, Hashtable.class});
    if (ctor != null) {
      return (RecordFile) ctor.newInstance(new Object[] {entry.getFile().toString(), properties});
    }
    ctor = Misc.findConstructor(c, new Class[] {String.class});

    if (ctor != null) {
      return (RecordFile) ctor.newInstance(new Object[] {entry.getResource().getPath()});
    }

    throw new IllegalArgumentException("Could not find constructor for " + className);
  }
  /**
   * _more_
   *
   * @param entry _more_
   * @return _more_
   * @throws Exception On badness
   */
  public Hashtable getRecordProperties(Entry entry) throws Exception {
    Object[] values = entry.getTypeHandler().getEntryValues(entry);
    String propertiesString =
        (values[IDX_PROPERTIES] != null) ? values[IDX_PROPERTIES].toString() : "";

    String typeProperties = getProperty("record.properties", (String) null);

    Hashtable p = null;

    if (typeProperties != null) {
      if (p == null) {
        p = new Hashtable();
      }
      p.putAll(RecordFile.getProperties(typeProperties));
    }

    if (propertiesString != null) {
      if (p == null) {
        p = new Hashtable();
      }
      p.putAll(RecordFile.getProperties(propertiesString));
    }

    return p;
  }
  /**
   * _more_
   *
   * @param entry _more_
   * @param originalFile _more_
   * @throws Exception _more_
   */
  public void initializeEntry(Entry entry, File originalFile) throws Exception {

    if (anySuperTypesOfThisType()) {
      return;
    }
    Hashtable existingProperties = getRecordProperties(entry);
    if ((existingProperties != null) && (existingProperties.size() > 0)) {
      return;
    }

    // Look around for properties files that define
    // the crs, fields for text formats, etc.
    Hashtable properties =
        RecordFile.getPropertiesForFile(originalFile.toString(), PointFile.DFLT_PROPERTIES_FILE);

    // Make the properties string
    String contents = makePropertiesString(properties);
    Object[] values = entry.getTypeHandler().getEntryValues(entry);
    // Append the properties file contents
    if (values[IDX_PROPERTIES] != null) {
      values[IDX_PROPERTIES] = "\n" + contents;
    } else {
      values[IDX_PROPERTIES] = contents;
    }
  }
  /**
   * _more_
   *
   * @param entry _more_
   * @param properties _more_
   * @return _more_
   * @throws Exception _more_
   */
  private RecordFile doMakeRecordFile(Entry entry, Hashtable properties) throws Exception {
    String recordFileClass = getProperty("record.file.class", (String) null);
    if (recordFileClass != null) {
      return doMakeRecordFile(entry, recordFileClass, properties);
    }
    String path = entry.getFile().toString();

    return (RecordFile) getRecordFileFactory().doMakeRecordFile(path, properties);
  }
  /**
   * _more_
   *
   * @param entry _more_
   * @return _more_
   */
  @Override
  public String getEntryName(Entry entry) {
    String name = super.getEntryName(entry);
    if (!Utils.stringDefined(name)) {
      name = entry.getValue(0, "");
    }

    //        System.err.println("NAME:" + name);
    return name;
  }
  /**
   * @param request _more_
   * @param entry _more_
   * @param map _more_
   * @return _more_
   */
  @Override
  public boolean addToMap(Request request, Entry entry, MapInfo map) {
    try {
      if (!entry.isFile()) {
        return true;
      }
      // TODO: stream through the shapes
      EsriShapefile shapefile = new EsriShapefile(entry.getFile().toString());
      List features = shapefile.getFeatures();
      int totalPoints = 0;
      int MAX_POINTS = 10000;
      for (int i = 0; i < features.size(); i++) {
        if (totalPoints > MAX_POINTS) {
          break;
        }
        EsriShapefile.EsriFeature gf = (EsriShapefile.EsriFeature) features.get(i);
        java.util.Iterator pi = gf.getGisParts();
        while (pi.hasNext()) {
          if (totalPoints > MAX_POINTS) {
            break;
          }
          GisPart gp = (GisPart) pi.next();
          double[] xx = gp.getX();
          double[] yy = gp.getY();
          List<double[]> points = new ArrayList<double[]>();
          for (int ptIdx = 0; ptIdx < xx.length; ptIdx++) {
            points.add(new double[] {yy[ptIdx], xx[ptIdx]});
          }
          totalPoints += points.size();
          if (points.size() > 1) {
            map.addLines("", points);
          } else if (points.size() == 1) {
            map.addMarker("id", points.get(0)[0], points.get(0)[1], null, "");
          }
        }
      }
    } catch (Exception exc) {
      throw new RuntimeException(exc);
    }

    return false;
  }
  /**
   * _more_
   *
   * @param request _more_
   * @param entry _more_
   * @return _more_
   * @throws Exception _more_
   */
  @Override
  public String getIconUrl(Request request, Entry entry) throws Exception {
    double depth = entry.getValue(4, 0.0);
    if (depth == 0) {
      return iconUrl("/incident/flag_green.png");
    }
    if (depth <= 2) {
      return iconUrl("/incident/flag_blue.png");
    }

    return iconUrl("/incident/flag_red.png");
  }
 /**
  * @param request _more_
  * @param entry _more_
  */
 private void georeferenceEntry(Request request, Entry entry) {
   if (entry.isGeoreferenced()) {
     return;
   }
   // TODO: if the entry has a location then don't do this?
   String address = entry.getValue(0, (String) null);
   String city = entry.getValue(1, (String) null);
   String state = entry.getValue(2, (String) null);
   if (!Utils.stringDefined(address)) {
     return;
   }
   String fullAddress = address + "," + city + "," + state;
   double[] loc = GeoUtils.getLocationFromAddress(fullAddress);
   if (loc == null) {
     System.err.println("no geo for address:" + fullAddress);
   } else {
     System.err.println("got geo for address:" + fullAddress);
     entry.setLatitude(loc[0]);
     entry.setLongitude(loc[1]);
   }
 }
 /**
  * _more_
  *
  * @param request _more_
  * @param entry _more_
  * @param parent _more_
  * @param newEntry _more_
  * @throws Exception _more_
  */
 public void initializeEntryFromForm(Request request, Entry entry, Entry parent, boolean newEntry)
     throws Exception {
   if (!entry.isFile()) {
     return;
   }
   EsriShapefile shapefile = new EsriShapefile(entry.getFile().toString());
   Rectangle2D bounds = shapefile.getBoundingBox();
   double[][] lonlat = new double[][] {{bounds.getX()}, {bounds.getY() + bounds.getHeight()}};
   ProjFile projFile = shapefile.getProjFile();
   if (projFile != null) {
     lonlat = projFile.convertToLonLat(lonlat);
   }
   entry.setNorth(lonlat[IDX_LAT][0]);
   entry.setWest(lonlat[IDX_LON][0]);
   lonlat[IDX_LAT][0] = bounds.getY();
   lonlat[IDX_LON][0] = bounds.getX() + bounds.getWidth();
   if (projFile != null) {
     lonlat = projFile.convertToLonLat(lonlat);
   }
   entry.setSouth(lonlat[IDX_LAT][0]);
   entry.setEast(lonlat[IDX_LON][0]);
 }