From 142c51d25c7f5b1aa7fc98571328ee1d5ca34775 Mon Sep 17 00:00:00 2001 From: "Ruben O. Chiavone" Date: Sat, 5 Dec 2020 16:00:17 -0300 Subject: [PATCH] Implement response parser for EnhancedImplementation --- .../java/rastreio/DefaultImplementation.java | 2 +- .../java/rastreio/EnhancedImplementation.java | 137 +++- .../java/rastreio/RastreioMockedTest.java | 691 +++++++++--------- src/test/java/rastreio/RastreioTest.java | 641 ++++++++++------ src/test/java/rastreio/Util.java | 3 + 5 files changed, 894 insertions(+), 580 deletions(-) diff --git a/src/main/java/rastreio/DefaultImplementation.java b/src/main/java/rastreio/DefaultImplementation.java index a8c9155..99e7b81 100644 --- a/src/main/java/rastreio/DefaultImplementation.java +++ b/src/main/java/rastreio/DefaultImplementation.java @@ -87,7 +87,7 @@ private static Request newRequest(String objectCode) { * @param response response data to be parsed * @return new tracking object */ - public static TrackObject parseResponse(String objectCode, String response) { + private TrackObject parseResponse(String objectCode, String response) { TrackObjectServiceType serviceType = TrackObjectServiceType.UNKNOWN; try { diff --git a/src/main/java/rastreio/EnhancedImplementation.java b/src/main/java/rastreio/EnhancedImplementation.java index dd48b5b..ac60bc1 100644 --- a/src/main/java/rastreio/EnhancedImplementation.java +++ b/src/main/java/rastreio/EnhancedImplementation.java @@ -1,6 +1,9 @@ package rastreio; import java.io.IOException; +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; @@ -17,12 +20,17 @@ import okhttp3.RequestBody; import okhttp3.Response; import okhttp3.ResponseBody; +import org.jsoup.Jsoup; +import org.jsoup.nodes.Document; +import org.jsoup.nodes.Element; +import org.jsoup.select.Elements; /** * Enhanced implementation using OkHttp and Jsoup (from DefaultImplementation). */ public class EnhancedImplementation implements Implementation { private static final OkHttpClient HTTP_CLIENT; + private static final DateFormat DATE_FORMAT = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss SSS"); static { HTTP_CLIENT = new OkHttpClient.Builder() @@ -47,8 +55,7 @@ public void onResponse(Call call, Response response) throws IOException { } try (ResponseBody responseBody = response.body()) { // Parse response and notify listener about new tacking object - listener.onSuccess(DefaultImplementation.parseResponse(objectCode, - responseBody.string())); + listener.onSuccess(parseResponse(objectCode, responseBody.string())); } catch (IOException e) { listener.onFailure(new Exception("Rastreio.track: unable to fullfill HTTP request", e)); } @@ -71,7 +78,7 @@ public TrackObject trackSync(String objectCode) throws IOException { ((InMemoryCookieJar) HTTP_CLIENT.cookieJar()).clear(); } // Parse response and return new tacking object - return DefaultImplementation.parseResponse(objectCode, response.body().string()); + return parseResponse(objectCode, response.body().string()); } catch (IOException e) { throw new IOException("Rastreio.trackSync: unable to fullfill HTTP request", e); } @@ -101,6 +108,130 @@ private static Request newRequest(String objectCode) { return request; } + /** + * Parse response data and create new tracking object. + * @param objectCode tracking object code + * @param response response data to be parsed + * @return new tracking object + */ + private TrackObject parseResponse(String objectCode, String response) { + TrackObjectServiceType serviceType = TrackObjectServiceType.UNKNOWN; + + try { + serviceType = TrackObjectServiceType.valueOf(objectCode.substring(0, 2)); + } catch (Exception e) { + // ignore + } + + TrackObject trackObject = new TrackObject(); + trackObject.setCode(objectCode); + trackObject.setServiceType(serviceType); + trackObject.setError(Error.OBJECT_NOT_FOUND); + trackObject.setValid(false); + trackObject.setDelivered(false); + + Document document = Jsoup.parse(response); + Elements elements = document.getElementsByClass("listEvent"); + + if (elements.isEmpty()) { + return trackObject; + } + + ArrayList events = new ArrayList(); + + for (Element eventListItem : elements) { + elements = eventListItem.getElementsByTag("tr").first().getElementsByTag("td"); + + if (elements.size() != 2) { + System.out.println("Rastreio.parseResponse: couldn't find enough table data elements"); + continue; // Skip invalid table row + } + + final Element eventListFirstData = elements.first(); + final Element eventListLastData = elements.last(); + + String eventListFirstDataHtml = eventListFirstData.html(); + String[] eventListFirstDataPieces = eventListFirstDataHtml.trim().split("
"); + + if (eventListFirstDataPieces.length != 3) { + System.out + .println("Rastreio.parseResponse: couldn't parse first table data element properly"); + continue; // Skip invalid table row + } + + String eventDate = eventListFirstDataPieces[0].trim(); + String eventTime = eventListFirstDataPieces[1].trim(); + + elements = eventListFirstData.getElementsByTag("label"); + + String locale = null; + + if (!elements.isEmpty()) { + locale = elements.first().text().trim(); + } else { + locale = eventListFirstDataPieces[2].trim(); + } + + String eventListLastDataHtml = eventListLastData.html(); + String[] eventListLastDataPieces = eventListLastDataHtml.trim().split("
"); + + elements = eventListLastData.getElementsByTag("strong"); + + String description = null; + + if (!elements.isEmpty()) { + // Get `strong` node content + description = elements.first().text().trim(); + } else if (eventListLastDataPieces.length > 0) { + // Get first string element as event description + description = eventListLastDataPieces[0].trim(); + } + + if (description == null || description.isEmpty()) { + System.out + .println("Rastreio.parseResponse: couldn't parse last table data element properly"); + continue; // Skip invalid table row + } + + String details = null; + + if (eventListLastDataPieces.length > 1 + && !eventListLastDataPieces[1].trim().startsWith("