import java.io.File;
import java.util.TreeSet;
import org.apache.commons.digester3.Digester;

public class GetMillionCities {
  public static class CityCollection extends TreeSet<City>  {
      public void addCity(City c) { if (c.population > 1000000) this.add(c);}  }
  public static void listCities(CityCollection cities) {
      for (City c : cities) {
         System.out.println(c.name + " " + c.country + " " + c.population); }  }
  public static class City implements Comparable{
    String name = null;
    String country = null;
    int population = -1;
    public void setName(String n) { if (name == null) name = n; }
    public void setCountry(String code) { this.country = code; }
    // note: all PCDATA/CDATA values are strings!
    public void setPopulation(String pop) { this.population = new Integer(pop); }
    public int compareTo(Object o) {
         if (this.population < ((City)o).population) return 1; else return -1; }
  }
  // continue next page









  public static void main(String[] args) {
    File mondial = new File("mondial.xml");
    final Digester digester = new Digester();
    digester.push(new CityCollection());

    // note: reacts only on cities as direct children of countries
    // */city would take all cities,
    // country//city, country/*/city, mondial/*/city are not allowed;
    digester.addObjectCreate("mondial/country/city", City.class);
    digester.addSetProperties("mondial/country/city", "country", "country");
    digester.addBeanPropertySetter("mondial/country/city/name");
    digester.addCallMethod("mondial/country/city/population", "setPopulation", 1);
    digester.addCallParam("mondial/country/city/population", 0);
    // Digester (clearly) does not like population[last()]. //
    // note: at the end, the last=most recent population is the stored value
    // at </city> calls addCity() of the now-top-of-stack-object which is the CityCollection
    digester.addSetNext("mondial/country/city", "addCity");
    try { digester.setValidating(false);
          final CityCollection cities = digester.parse(mondial);
          System.out.println("####  now listing cities #### ");
          listCities(cities);
        } catch (Exception e) { e.printStackTrace(); }
} }
