001package edu.pdx.cs.joy.servlets;
002
003import edu.pdx.cs.joy.family.FamilyTree;
004import edu.pdx.cs.joy.family.Person;
005import edu.pdx.cs.joy.family.XmlDumper;
006import jakarta.servlet.ServletConfig;
007import jakarta.servlet.http.HttpServlet;
008import jakarta.servlet.http.HttpServletRequest;
009import jakarta.servlet.http.HttpServletResponse;
010
011import java.io.IOException;
012import java.io.PrintWriter;
013import java.util.Collection;
014import java.util.Date;
015
016/**
017 * A servlet that provides access to a {@link FamilyTree} via REST
018 *
019 * @since Summer 2008
020 */
021public class FamilyTreeServlet extends HttpServlet {
022  private FamilyTree tree;
023
024  private int nextPersonId = 1;
025
026  @Override
027  public void init(ServletConfig servletConfig) {
028    tree = new FamilyTree();
029  }
030
031  @Override
032  protected void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
033    createPerson(request, response);
034  }
035
036  @Override
037  protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
038    String uri = request.getRequestURI();
039    String lastPart = uri.substring(uri.lastIndexOf('/') + 1, uri.length());
040
041    if (lastPart.equals("person")) {
042      Collection<Person> all = this.tree.getPeople();
043      writePeople(response, all.toArray(new Person[all.size()]));
044
045    } else {
046      try {
047        int id = Integer.parseInt(lastPart);
048        Person person = this.tree.getPerson(id);
049        if (person == null) {
050          response.sendError(HttpServletResponse.SC_NOT_FOUND);
051          
052        } else {
053         writePeople(response, person);
054        }
055
056      } catch (NumberFormatException ex) {
057        response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Malformed person id: " + lastPart);
058        return;
059      }
060    }
061  }
062
063  private void createPerson(HttpServletRequest request, HttpServletResponse response) throws IOException {
064    String gender = getParameter("Gender", request);
065    if (gender == null) {
066      response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Missing Gender");
067      return;
068    }
069
070    Person person;
071    try {
072      person = new Person(nextPersonId++, Person.Gender.valueOf(gender.toUpperCase()));
073
074    } catch (IllegalArgumentException ex) {
075      response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Bad Gender: " + gender);
076      return;
077    }
078
079    person.setFirstName(getParameter("FirstName", request));
080    person.setMiddleName(getParameter("MiddleName", request));
081    person.setLastName(getParameter("LastName", request));
082
083    String motherId = getParameter("MotherId", request);
084    if (motherId != null) {
085      try {
086        Person mother = tree.getPerson(Integer.parseInt(motherId));
087        if (mother == null) {
088          response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Unknown mother: " + motherId);
089          return;
090
091        } else {
092          person.setMother(mother);
093        }
094
095      } catch (NumberFormatException ex) {
096        response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Bad mother id: " + motherId);
097        return;
098      }
099    }
100
101    String fatherId = getParameter("FatherId", request);
102    if (fatherId != null) {
103      try {
104        Person father = tree.getPerson(Integer.parseInt(fatherId));
105        if (father == null) {
106          response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Unknown father: " + fatherId);
107          return;
108
109        } else {
110          person.setFather(father);
111        }
112
113      } catch (NumberFormatException ex) {
114        response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Bad father id: " + fatherId);
115        return;
116      }
117    }
118
119    String dob = getParameter("DateOfBirth", request);
120    if (dob != null) {
121      try {
122        person.setDateOfBirth(new Date(Long.parseLong(dob)));
123
124      } catch (NumberFormatException ex) {
125        response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Bad date of birth: " + dob);
126        return;
127      }
128    }
129
130    String dod = getParameter("DateOfDeath", request);
131    if (dod != null) {
132      try {
133        person.setDateOfDeath(new Date(Long.parseLong(dod)));
134
135      } catch (NumberFormatException ex) {
136        response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Bad date of death: " + dod);
137        return;
138      }
139    }
140
141    tree.addPerson(person);
142
143    writePeople(response, person);
144  }
145
146  /**
147   * Writes people to the response
148   */
149  private void writePeople(HttpServletResponse response, Person... people) throws IOException {
150    FamilyTree tree = new FamilyTree();
151    for (Person person : people) {
152      tree.addPerson(person);
153    }
154
155    new XmlDumper(new PrintWriter(response.getWriter(), true)).dump(tree);
156  }
157
158  private String getParameter(String name, HttpServletRequest request) {
159    String value = request.getParameter(name);
160    if (value == null || "".equals(value)) {
161      return null;
162
163    } else {
164      return value;
165    }
166  }
167}