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