001package edu.pdx.cs410J.family;
002
003import edu.pdx.cs410J.family.Person.Gender;
004
005import java.io.*;
006import java.text.*;
007import java.util.*;
008
009/**
010 * This program demonstrates some of the functionality of out family
011 * tree example by letting a user add people to a family tree that is
012 * stored in a given file.
013 *
014 * @author David Whitlock
015 * @since Fall 2000
016 */
017public class AddPerson {
018
019  // Save you fingers from typing "System.out" all the time
020  private static final PrintStream err = System.err;
021
022  // Data for a person
023  private static int id = 0;
024  private static String gender;
025  private static String fileName;
026  private static boolean useXml = false;  // Text file by default
027  private static String firstName;
028  private static String middleName;
029  private static String lastName;
030  private static Date dob;          // Date of birth
031  private static Date dod;          // Date of death
032  private static int childId = 0;
033
034  /**
035   * Displays a help message on how to use this program.
036   */
037  private static void usage(String s) {
038    err.println("\n** " + s + "\n");
039
040    err.println("Adds a person to a family tree");
041    err.println("usage: java AddPerson [options] <args>");
042    err.println("  args are (in this order):");
043    err.println("    file         File to store data in");
044    err.println("    id           Person's id (greater or equal to 1)");
045    err.println("    gender       Person's gender (male or female)");
046    err.println("    firstName    Person's first name");
047    err.println("    middleName   Person's middle name");
048    err.println("    lastName     Person's last name");
049    err.println("    dob          Person's date of birth " +
050      "(e.g. Jun 27, 1936)");
051    err.println("  options are (options may appear in any order):");
052    err.println("    -parentOf id       Person's child");
053    err.println("    -dod date          Person's date of death " +
054      "(e.g. Jan 12, 1987)");
055    err.println("    -xml               File in XML format instead of text");
056
057    err.println("\n");
058    System.exit(1);
059  }
060
061  /**
062   * Parses the command line.
063   *
064   * @return An error message if the command line was not parsed
065   *         sucessfully
066   */
067  private static String parseCommandLine(String[] args) {
068    DateFormat df = DateFormat.getDateInstance(DateFormat.MEDIUM);
069    df.setLenient(false);
070
071    for (int i = 0; i < args.length; i++) {
072      if (args[i].equals("-xml")) {
073        useXml = true;
074
075      } else if (args[i].equals("-dod")) {
076        if (++i >= args.length) {
077          return "Missing date of death";
078        }
079
080        // A date will take up three arguments
081        StringBuffer sb = new StringBuffer();
082        for (int j = 0; j < 3; j++) {
083          if (i >= args.length) {
084            return "Malformatted date of death: " + sb;
085
086          } else {
087            sb.append(args[i]).append(" ");
088          }
089          i++;
090        }
091
092        try {
093          dod = df.parse(sb.toString().trim());
094
095        } catch (ParseException ex) {
096          return "Malformatted date of death: " + sb;
097        }
098
099      } else if (args[i].equals("-parentOf")) {
100        if (++i >= args.length) {
101          return "No child id specified";
102        }
103
104        try {
105          childId = Integer.parseInt(args[i]);
106
107        } catch (NumberFormatException ex) {
108          return "Malformatted child id: " + args[i];
109        }
110
111        if (childId < 1) {
112          return "Invalid child id value: " + childId;
113        }
114
115      } else if (fileName == null) {
116
117        fileName = args[i];
118
119      } else if (id == 0) {
120        try {
121          id = Integer.parseInt(args[i]);
122
123        } catch (NumberFormatException ex) {
124          return "Malformatted id: " + args[i];
125        }
126
127        if (id < 1) {
128          return "Invalid id value: " + id;
129        }
130
131      } else if (gender == null) {
132
133        gender = args[i];
134
135      } else if (firstName == null) {
136
137        firstName = args[i];
138
139      } else if (middleName == null) {
140
141        middleName = args[i];
142
143      } else if (lastName == null) {
144
145        lastName = args[i];
146
147      } else if (dob == null) {
148        // A date will take up three arguments
149        StringBuffer sb = new StringBuffer();
150        for (int j = 0; j < 3; j++) {
151          if (i >= args.length) {
152            return "Malformatted date of birth: " + sb;
153
154          } else {
155            sb.append(args[i]).append(" ");
156          }
157
158          i++;
159        }
160
161        try {
162          dob = df.parse(sb.toString().trim());
163
164        } catch (ParseException ex) {
165          return "Malformatted date of birth: " + sb;
166        }
167
168      } else {
169        return ("Unknown command line option: " + args[i]);
170      }
171    }
172
173    // Make some additional checks
174    if (id == 0) {
175      return "No id specified";
176
177    } else if (fileName == null) {
178      return "No file name specified";
179
180    } else if (gender == null) {
181      return "Missing gender";
182
183    } else if (firstName == null) {
184      return "Missing first name";
185
186    } else if (middleName == null) {
187      return "Missing middle name";
188
189    } else if (lastName == null) {
190      return "Missing last name";
191    }
192
193    // No errors!
194    return null;
195  }
196
197  /**
198   * Main program that parsers the command line and adds a person to a
199   * family tree.
200   */
201  public static void main(String[] args) {
202    // First parse the command line
203    String message = parseCommandLine(args);
204
205    if (message != null) {
206      // An error occurred, report it
207      usage(message);
208    }
209
210    FamilyTree tree = null;
211
212    // If the data file exists, read it in
213    File file = new File(fileName);
214    if (file.exists()) {
215      Parser parser = null;
216      if (useXml) {
217        // File in XML format
218        try {
219          parser = new XmlParser(file);
220
221        } catch (FileNotFoundException ex) {
222          err.println("** Could not find file " + fileName);
223          System.exit(1);
224        }
225
226      } else {
227        // File in text format
228        try {
229          parser = new TextParser(file);
230
231        } catch (FileNotFoundException ex) {
232          err.println("** Could not find file " + fileName);
233          System.exit(1);
234        }
235
236      }
237
238      try {
239        tree = parser.parse();
240
241      } catch (FamilyTreeException ex) {
242        err.println("** File " + fileName + " is malformatted");
243        System.exit(1);
244      }
245
246    } else {
247      // No file to read, create a new family tree
248      tree = new FamilyTree();
249    }
250
251    // Get a person and update its information
252    Person person = tree.getPerson(id);
253
254    if (person == null) {
255      Gender g;
256
257      if (gender == null) {
258        String s = "Must specify a gender when creating a new person";
259        err.println(s);
260        System.exit(1);
261        g = null;                 // Keep compiler from complaining
262
263      } else if (gender.equalsIgnoreCase("male")) {
264        g = Person.MALE;
265
266      } else if (gender.equalsIgnoreCase("female")) {
267        g = Person.FEMALE;
268
269      } else {
270        err.println("** Illegal gender: " + gender);
271        System.exit(1);
272        g = null;
273      }
274
275      person = new Person(id, g);
276      tree.addPerson(person);
277    }
278
279    person.setFirstName(firstName);
280    person.setMiddleName(middleName);
281    person.setLastName(lastName);
282
283    if (dob != null) {
284      person.setDateOfBirth(dob);
285    }
286
287    if (dod != null) {
288      person.setDateOfDeath(dod);
289    }
290
291    if (childId != 0) {
292      // Make a child aware of his/her parent
293      Person child = tree.getPerson(childId);
294      if (child == null) {
295        String s = "The child with id " + childId +
296          " does not exist";
297        err.println("\n** " + s + "\n");
298        System.exit(1);
299      }
300
301      if (person.getGender() == Person.MALE) {
302        child.setFather(person);
303
304      } else {
305        child.setMother(person);
306      }
307    }
308
309    // Now write the family tree to the file
310    Dumper dumper = null;
311    if (useXml) {
312      try {
313        dumper = new XmlDumper(file);
314
315      } catch (IOException ex) {
316        err.println("** Error while dealing with " + file);
317        System.exit(1);
318      }
319
320    } else {
321      try {
322        dumper = new TextDumper(file);
323
324      } catch (IOException ex) {
325        err.println("** Error while dealing with " + file);
326        System.exit(1);
327      }
328    }
329    dumper.dump(tree);
330
331  }
332
333}