package app.abhijit.iter.data; import android.support.annotation.NonNull; import com.google.gson.JsonArray; import com.google.gson.JsonObject; import com.google.gson.JsonParser; import org.apache.commons.lang3.text.WordUtils; import java.util.Arrays; import java.util.Comparator; import java.util.Date; import java.util.HashMap; import java.util.regex.Matcher; import java.util.regex.Pattern; import app.abhijit.iter.exceptions.InvalidCredentialsException; import app.abhijit.iter.exceptions.InvalidResponseException; import app.abhijit.iter.models.Student; import app.abhijit.iter.models.Subject; /** * This class validates and parses the api response into a Student object. */ class ResponseParser { private JsonParser jsonParser; ResponseParser() { this.jsonParser = new JsonParser(); } @NonNull String parseRegistrationId(@NonNull String registrationIdJson) throws InvalidResponseException { JsonObject registrationId; try { registrationId = this.jsonParser.parse(registrationIdJson).getAsJsonObject(); } catch (Exception e) { throw new InvalidResponseException(); } if (!registrationId.has("studentdata")) { throw new InvalidCredentialsException(); } JsonArray studentData = registrationId.getAsJsonArray("studentdata"); if (studentData.size() == 0) { throw new InvalidResponseException(); } JsonObject[] years = new JsonObject[studentData.size()]; for (int i = 0; i < studentData.size(); i++) { years[i] = studentData.get(i).getAsJsonObject(); if (!years[i].has("REGISTRATIONID") || !years[i].has("REGISTRATIONDATEFROM")) { throw new InvalidResponseException(); } } Arrays.sort(years, new Comparator<JsonObject>() { @Override public int compare(JsonObject o1, JsonObject o2) { return o1.get("REGISTRATIONDATEFROM").getAsString().compareTo(o2.get("REGISTRATIONDATEFROM").getAsString()); } }); return years[years.length - 1].get("REGISTRATIONID").getAsString(); } @NonNull Student parseStudent(@NonNull String loginJson, @NonNull String attendanceJson) throws InvalidCredentialsException, InvalidResponseException { Student student = processLogin(loginJson); try { student.subjects.putAll(processAttendance(attendanceJson)); } catch (InvalidResponseException ignored) { } return student; } private Student processLogin(String loginJson) { JsonObject login; try { login = this.jsonParser.parse(loginJson).getAsJsonObject(); } catch (Exception e) { throw new InvalidResponseException(); } if (!login.has("status") || !login.has("name")) { throw new InvalidResponseException(); } if (!login.get("status").getAsString().equals("success")) { throw new InvalidCredentialsException(); } Student student = new Student(); student.name = WordUtils.capitalizeFully(login.get("name").getAsString()); return student; } private HashMap<String, Subject> processAttendance(String attendanceJson) { JsonArray attendance; try { attendance = this.jsonParser.parse(attendanceJson) .getAsJsonObject().get("griddata").getAsJsonArray(); } catch (Exception e) { throw new InvalidResponseException(); } HashMap<String, Subject> subjects = new HashMap<>(); Pattern classesPattern = Pattern.compile("^(\\d+) / (\\d+)$"); for (int i = 0; i < attendance.size(); i++) { JsonObject s = attendance.get(i).getAsJsonObject(); if (!s.has("Latt") || !s.has("Patt") || !s.has("subject") || !s.has("subjectcode")) { throw new InvalidResponseException(); } Subject subject = new Subject(); subject.name = s.get("subject").getAsString(); subject.code = s.get("subjectcode").getAsString(); subject.lastUpdated = new Date().getTime(); Matcher theoryClassesMatcher = classesPattern.matcher(s.get("Latt").getAsString()); if (theoryClassesMatcher.find()) { subject.theoryPresent = Integer.parseInt(theoryClassesMatcher.group(1)); subject.theoryTotal = Integer.parseInt(theoryClassesMatcher.group(2)); } Matcher labClassesMatcher = classesPattern.matcher(s.get("Patt").getAsString()); if (labClassesMatcher.find()) { subject.labPresent = Integer.parseInt(labClassesMatcher.group(1)); subject.labTotal = Integer.parseInt(labClassesMatcher.group(2)); } subjects.put(subject.code, subject); } return subjects; } }