Skip to content
This repository has been archived by the owner on Apr 16, 2024. It is now read-only.

Add implementation for linketrack tracking API #33

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,6 @@ bin
# Ignore some docs files
docs/node_modules
docs/dist

# Private file
src/test/resources/url_token.txt
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

- Implementation for Link&Track API, LinkETrackImplementation
- Support for dependency injection
- Mockito support
- Deprecate EnhancedImplementation and DefaultImplementation

## [1.1.0] - 2021-06-06
### Changed

Expand Down
8 changes: 8 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,18 @@ repositories {
dependencies {
implementation 'com.squareup.okhttp3:okhttp:4.9.1'
implementation 'org.jsoup:jsoup:1.13.1'
implementation 'org.json:json:20210307'

// Dependency injection
implementation 'javax.inject:javax.inject:1'

// Use JUnit test framework
testImplementation 'junit:junit:4.12'
testImplementation 'com.squareup.okhttp3:mockwebserver:4.9.1'

// Mockito
testImplementation 'org.mockito:mockito-core:4.0.0'
testImplementation 'net.bytebuddy:byte-buddy:1.11.20'
}

test {
Expand Down
60 changes: 9 additions & 51 deletions src/main/java/rastreio/DefaultImplementation.java
Original file line number Diff line number Diff line change
@@ -1,18 +1,11 @@
package rastreio;

import java.io.IOException;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import okhttp3.Call;
import okhttp3.Callback;
import javax.inject.Inject;
import okhttp3.FormBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import okhttp3.ResponseBody;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
Expand All @@ -21,60 +14,25 @@
/**
* Default implementation using OkHttp and Jsoup.
*/
public class DefaultImplementation implements Implementation {
private static final OkHttpClient HTTP_CLIENT = new OkHttpClient();
private static final DateFormat DATE_FORMAT = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss SSS");
@Deprecated
public class DefaultImplementation extends Implementation {

@Override
public void track(String objectCode, Rastreio.Listener listener) {
HTTP_CLIENT.newCall(newRequest(objectCode)).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
listener.onFailure(new Exception("Rastreio.track: unable to fullfill HTTP request", e));
}

@Override
public void onResponse(Call call, Response response) throws IOException {
if (response == null || !response.isSuccessful()) {
listener.onFailure(new IOException("Rastreio.track: erroneous HTTP response "
+ response));
}
try (ResponseBody responseBody = response.body()) {
// Parse response and notify listener about new tacking object
listener.onSuccess(parseResponse(objectCode, responseBody.string()));
} catch (IOException e) {
listener.onFailure(new Exception("Rastreio.track: unable to fullfill HTTP request", e));
}
}
});
}

@Override
public TrackObject trackSync(String objectCode) throws IOException {
try (Response response = HTTP_CLIENT.newCall(newRequest(objectCode)).execute()) {
if (response == null || !response.isSuccessful()) {
throw new IOException("Rastreio.trackSync: erroneous HTTP response code " + response);
}

// Parse response and return new tacking object
return parseResponse(objectCode, response.body().string());
} catch (IOException e) {
throw new IOException("Rastreio.trackSync: unable to fullfill HTTP request", e);
}
}
@Inject
private Magic mMagic;

/**
* Create new request object.
* @param objectCode tracking object code
* @return new request object
*/
private static Request newRequest(String objectCode) {
@Override
protected Request newRequest(String objectCode) {
RequestBody formBody = new FormBody.Builder()
.add("objetos", objectCode)
.build();

Request request = new Request.Builder()
.url(Magic.URL)
.url(mMagic.getUrl())
.post(formBody)
.build();

Expand All @@ -87,7 +45,7 @@ private static Request newRequest(String objectCode) {
* @param response response data to be parsed
* @return new tracking object
*/
private TrackObject parseResponse(String objectCode, String response) {
protected TrackObject parseResponse(String objectCode, String response) {
TrackObjectServiceType serviceType = TrackObjectServiceType.UNKNOWN;

try {
Expand Down
44 changes: 25 additions & 19 deletions src/main/java/rastreio/EnhancedImplementation.java
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
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;
import java.util.List;
import java.util.Set;
import javax.inject.Inject;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.Cookie;
Expand All @@ -28,20 +27,25 @@
/**
* 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");
@Deprecated
public class EnhancedImplementation extends Implementation {

static {
HTTP_CLIENT = new OkHttpClient.Builder()
@Inject
private Magic mMagic;

/**
* Create a new object.
*/
public EnhancedImplementation() {
super(new OkHttpClient.Builder()
.cookieJar(new InMemoryCookieJar())
.followRedirects(true)
.build();
.build());
}

@Override
public void track(String objectCode, Rastreio.Listener listener) {
HTTP_CLIENT.newCall(newRequest(objectCode)).enqueue(new Callback() {
mHttpClient.newCall(newRequest(objectCode)).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
listener.onFailure(new Exception("Rastreio.track: unable to fullfill HTTP request", e));
Expand All @@ -60,22 +64,22 @@ public void onResponse(Call call, Response response) throws IOException {
listener.onFailure(new Exception("Rastreio.track: unable to fullfill HTTP request", e));
}
// Clear cookie jar after each response
if (HTTP_CLIENT.cookieJar() instanceof InMemoryCookieJar) {
((InMemoryCookieJar) HTTP_CLIENT.cookieJar()).clear();
if (mHttpClient.cookieJar() instanceof InMemoryCookieJar) {
((InMemoryCookieJar) mHttpClient.cookieJar()).clear();
}
}
});
}

@Override
public TrackObject trackSync(String objectCode) throws IOException {
try (Response response = HTTP_CLIENT.newCall(newRequest(objectCode)).execute()) {
try (Response response = mHttpClient.newCall(newRequest(objectCode)).execute()) {
if (response == null || !response.isSuccessful()) {
throw new IOException("Rastreio.trackSync: erroneous HTTP response code " + response);
}
// Clear cookie jar after each response
if (HTTP_CLIENT.cookieJar() instanceof InMemoryCookieJar) {
((InMemoryCookieJar) HTTP_CLIENT.cookieJar()).clear();
if (mHttpClient.cookieJar() instanceof InMemoryCookieJar) {
((InMemoryCookieJar) mHttpClient.cookieJar()).clear();
}
// Parse response and return new tacking object
return parseResponse(objectCode, response.body().string());
Expand All @@ -89,20 +93,21 @@ public TrackObject trackSync(String objectCode) throws IOException {
* @param objectCode tracking object code
* @return new request object
*/
private static Request newRequest(String objectCode) {
@Override
protected Request newRequest(String objectCode) {
RequestBody formBody = new FormBody.Builder()
.add("objetos", objectCode)
.add("acao", "track")
.build();

Request request = new Request.Builder()
.url(Magic.URL2)
.url(mMagic.getUrl2())
.post(formBody)
.build();

// Clear cookie jar before each request
if (HTTP_CLIENT.cookieJar() instanceof InMemoryCookieJar) {
((InMemoryCookieJar) HTTP_CLIENT.cookieJar()).clear();
if (mHttpClient.cookieJar() instanceof InMemoryCookieJar) {
((InMemoryCookieJar) mHttpClient.cookieJar()).clear();
}

return request;
Expand All @@ -114,7 +119,8 @@ private static Request newRequest(String objectCode) {
* @param response response data to be parsed
* @return new tracking object
*/
private TrackObject parseResponse(String objectCode, String response) {
@Override
protected TrackObject parseResponse(String objectCode, String response) {
TrackObjectServiceType serviceType = TrackObjectServiceType.UNKNOWN;

try {
Expand Down
81 changes: 77 additions & 4 deletions src/main/java/rastreio/Implementation.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,30 @@
package rastreio;

import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.ResponseBody;

/**
* Rastreio implementation interface.
* Rastreio implementation abstract class.
*/
public interface Implementation {
public abstract class Implementation {
protected static final DateFormat DATE_FORMAT = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss SSS");
protected final OkHttpClient mHttpClient;

protected Implementation(OkHttpClient httpClient) {
mHttpClient = httpClient;
}

public Implementation() {
mHttpClient = new OkHttpClient();
}

/**
* Track an object by its code asynchronously.
*
Expand All @@ -13,7 +34,31 @@ public interface Implementation {
* @param listener listener to be called when object tracking is completed
* @see Rastreio.Listener
*/
void track(String objectCode, Rastreio.Listener listener);
void track(String objectCode, Rastreio.Listener listener) {
mHttpClient.newCall(newRequest(objectCode)).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();
listener.onFailure(new Exception("Rastreio.track: unable to fullfill HTTP request", e));
}

@Override
public void onResponse(Call call, Response response) throws IOException {
if (response == null || !response.isSuccessful()) {
listener.onFailure(new IOException("Rastreio.track: erroneous HTTP response "
+ response));
}
try (ResponseBody responseBody = response.body()) {
// Parse response and notify listener about new tacking object
listener.onSuccess(parseResponse(objectCode, responseBody.string()));
} catch (IOException e) {
listener.onFailure(new Exception("Rastreio.track: unable to fullfill HTTP request",
Implementation.this instanceof ImplementationWithUrlToken
? new Exception("Suppressed exception: " + e.getCause()) : e));
}
}
});
}

/**
* Track an object by its code synchronously.
Expand All @@ -23,5 +68,33 @@ public interface Implementation {
* @throws java.io.IOException if a network error occur
* @see TrackObject
*/
TrackObject trackSync(String objectCode) throws java.io.IOException;
public TrackObject trackSync(String objectCode) throws IOException {
try (Response response = mHttpClient.newCall(newRequest(objectCode)).execute()) {
if (response == null || !response.isSuccessful()) {
throw new IOException("Rastreio.trackSync: erroneous HTTP response code " + response);
}

// Parse response and return new tacking object
return parseResponse(objectCode, response.body().string());
} catch (IOException e) {
throw new IOException("Rastreio.trackSync: unable to fullfill HTTP request",
this instanceof ImplementationWithUrlToken
? new Exception("Suppressed exception: " + e.getCause()) : e);
}
}

/**
* Create new request object.
* @param objectCode tracking object code
* @return new request object
*/
protected abstract Request newRequest(String objectCode);

/**
* Parse response data and create new tracking object.
* @param objectCode tracking object code
* @param response response data to be parsed
* @return new tracking object
*/
protected abstract TrackObject parseResponse(String objectCode, String response);
}
17 changes: 17 additions & 0 deletions src/main/java/rastreio/ImplementationWithUrlToken.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package rastreio;

/**
* Rastreio implementation that needs an URL with token.
*/
public abstract class ImplementationWithUrlToken extends Implementation {
protected String mUrlToken;

/**
* Set URL with token.
*
* @param urlToken string representing the private URL and token to be used
*/
public void setUrlToken(String urlToken) {
this.mUrlToken = urlToken;
}
}
Loading