001package edu.pdx.cs410J.family; 002 003import java.io.*; 004import java.text.*; 005import java.util.*; 006 007/** 008 * This class dumps a family tree to a text file in a format that can 009 * be read by a person. 010 * 011 * @author David Whitlock 012 */ 013public class PrettyPrinter implements Dumper { 014 015 private PrintWriter pw; // Where to pretty print to 016 017 /** 018 * Creates a new pretty printer that prints to a file of a given 019 * name. If the file does not exist, it is created. 020 */ 021 public PrettyPrinter(String fileName) throws IOException { 022 this(new File(fileName)); 023 } 024 025 /** 026 * Creates a new pretty printer that prints to a given file. 027 */ 028 public PrettyPrinter(File file) throws IOException { 029 this(new PrintWriter(new FileWriter(file), true)); 030 } 031 032 /** 033 * Creates a new pretty printer that prints to a 034 * <code>PrintWriter</code>. This way, we can print to destinations 035 * other than files (such as the console). 036 */ 037 PrettyPrinter(PrintWriter pw) { 038 this.pw = pw; 039 } 040 041 /** 042 * Prints the contents of the given family tree in a human-readable 043 * format. 044 */ 045 public void dump(FamilyTree tree) { 046 047 // We want to print the contents of the family tree sorted by id 048 // number. We'll use an instance of PersonSorter along with a 049 // TreeSet to sort the Persons. 050 SortedSet<Person> sortedTree = new TreeSet<Person>(new PersonSorter()); 051 sortedTree.addAll(tree.getPeople()); 052 053 // Print a banner 054 pw.println("Your Family Tree\n"); 055 056 DateFormat df = DateFormat.getDateInstance(DateFormat.LONG); 057 058 // Iterate over the people in the sorted tree in order and print 059 // out a description of each person. 060 Iterator iter = sortedTree.iterator(); 061 while (iter.hasNext()) { 062 Person person = (Person) iter.next(); 063 064 pw.println("Person " + person.getId() + ": " + 065 person.getFullName()); 066 067 Date dob = person.getDateOfBirth(); 068 if (dob != null) { 069 pw.print(" Born on " + df.format(dob)); 070 } 071 072 Date dod = person.getDateOfDeath(); 073 if (dod != null) { 074 pw.print(", died on " + df.format(dod)); 075 } 076 077 if (dob != null || dod != null) { 078 // Only print a newline if a date was printed 079 pw.println(""); 080 } 081 082 Person mother = person.getMother(); 083 if (mother != null) { 084 pw.println(" Mother: " + mother.getFullName() + " (" + 085 mother.getId() + ")"); 086 } 087 088 Person father = person.getFather(); 089 if (father != null) { 090 pw.println(" Father: " + father.getFullName() + " (" + 091 father.getId() + ")"); 092 } 093 094 Iterator marriages = person.getMarriages().iterator(); 095 while (marriages.hasNext()) { 096 Marriage marriage = (Marriage) marriages.next(); 097 Person spouse; 098 099 if(marriage.getWife().equals(person)) { 100 spouse = marriage.getHusband(); 101 102 } else { 103 spouse = marriage.getWife(); 104 } 105 106 pw.print(" Married " + spouse.getFullName()); 107 108 Date date = marriage.getDate(); 109 if(date != null) { 110 pw.print(" on " + df.format(date)); 111 } 112 113 String location = marriage.getLocation(); 114 if(location != null) { 115 pw.print(" in " + location); 116 } 117 118 pw.println(""); 119 } 120 121 // Put a blank line between people for readability 122 pw.println(""); 123 124 } 125 126 // Flush and close the PrintWriter for good measure 127 pw.flush(); 128 pw.close(); 129 130 } 131 132 /** 133 * Inner class used only by the dump method. It is used to sort 134 * <code>Person</code>s by their id. 135 */ 136 class PersonSorter implements Comparator<Person> { 137 138 /** 139 * Compares two <code>Person</code>s. If the id of person one is less 140 * than the id of person two, then person one is less than person 141 * two. If the id of person one is greater than the id of person 142 * two, then person one greater than person two. If the id of 143 * person one is equal to the id of person two, then the two 144 * persons are equal. 145 */ 146 public int compare(Person p1, Person p2) { 147 return p1.getId() - p2.getId(); 148 } 149 150 /** 151 * Compares one <code>PersonSorter</code> to another. All 152 * <code>PersonSorter</code>s are the same. 153 */ 154 public boolean equals(Object o) { 155 if (o instanceof PersonSorter) { 156 return(true); 157 158 } else { 159 return(false); 160 } 161 } 162 163 } 164 165 /** 166 * Test program. Create a simple family tree and print it to the 167 * console. 168 */ 169 public static void main(String[] args) { 170 // Make some people 171 Person me = PersonMain.me(); 172 Person mom = PersonMain.mom(me); 173 Person dad = PersonMain.dad(me); 174 175 me.setMother(mom); 176 me.setFather(dad); 177 178 Marriage marriage = new Marriage(dad, mom); 179 marriage.setLocation("Durham, NH"); 180 181 try { 182 DateFormat df = DateFormat.getDateInstance(DateFormat.MEDIUM); 183 marriage.setDate(df.parse("Jul 12, 1969")); 184 185 } catch (ParseException ex) { 186 System.out.println("** Malformed marriage date?"); 187 System.exit(1); 188 } 189 190 mom.addMarriage(marriage); 191 dad.addMarriage(marriage); 192 193 // Create a family tree. Add people in an interesting order. 194 FamilyTree tree = new FamilyTree(); 195 tree.addPerson(dad); 196 tree.addPerson(mom); 197 tree.addPerson(me); 198 199 // Pretty print the tree to the console 200 PrintWriter out = new PrintWriter(System.out, true); 201 PrettyPrinter pretty = new PrettyPrinter(out); 202 pretty.dump(tree); 203 } 204 205}